Delphi: SQL Запрос в Omni Parallel. До каждой блокировки основного потока - PullRequest
1 голос
/ 04 августа 2020

У меня есть parallel.foreach l oop, которое блокирует ответ интерфейса. В l oop я вызываю функцию, которая вызывает хранимую процедуру mySQL. Я бы хотел, чтобы это происходило в фоновом режиме, но это не позволяет пользовательскому интерфейсу отвечать до тех пор, пока все элементы в l oop не будут завершены. Пользовательский интерфейс реагирует, запрос не выполняется. Есть ли способ убедиться, что вызов sql выполняется в фоновом режиме и позволяет пользователю продолжить?

    Loop := Parallel.ForEach(1, L.Count - 1)
    .TaskConfig(Parallel.TaskConfig.OnMessage(Self))
    .NoWait
    .OnStop(
      procedure(const task: IOmniTask)
      begin
        task.Invoke(
          procedure
          begin
            wait.Signal;
            Loop := nil;
          end);
      end);
 
    loop.PreserveOrder;
    Loop.CancelWith(CancelToken);
    Loop.Into(outQueue).Execute(
      procedure(const task: IOmniTask; const Value: integer; var Result: TOmniValue)
      var
        E: TEmployee;
      begin
        task.Comm.Send(WM_LOG, value);
        E := L[Value];
        ProcessEmployee(E);
        Result := TEmployee.Create;
        TEmployee(Result).EmployeeID := E.EmployeeID;
      end);

      wait.WaitFor;

l oop вызывает функцию ниже

    procedure TRun.ProcessEmployee(E: TEmployee);
    var
     Conn: TSQLConnection;
     MyQuery: TSQLQuery;
    begin
     Conn := CreateDatabase(nil);
     OpenDatabaseEx(Conn);
     MyQuery := CreateQuery(nil, Conn);
     try
      try
        MyQuery.SQL.Text := 'call sp_runEmployee(' + IntToStr(E.Com) + ',' + IntToStr(E.EmpNumber) + 
        ',' + IntToStr(E.TypeID) + ',51);';
        MyQuery.ExecSQL();
        Application.ProcessMessages;
        E.Status := True;
      except
      on Exc: exception do
       begin
        exit;
       end;
      end;
    finally
     Conn.Free;
     MyQuery.Free;
     end;
    end;

1 Ответ

1 голос
/ 04 августа 2020

Вы вызываете wait.WaitFor в основном потоке. Это предотвращает его запуск (и, среди прочего, обработку событий пользовательского интерфейса).

Вы должны проверять выполнение без блокировки. Например, проверив статус вашего условия wait в обратном вызове OnIdle.

...