-1
我有在OmniThreadLibrary中終止BackgroundWorker的問題。一切正常,但是當我想終止BackgroundWorker時,終止失敗並且BackgroundWorker仍然活着。因此,以批處理方式運行的整個應用程序仍然存在。Delphi OmniThreadLibrary 3.03b:IBackgroundWorker - 終止不起作用
procedure TEntityIndexer.StartReindex;
begin
if LoadTable then
begin
// In a ProcessRecords method I schedule WorkItems for background tasks
ProcessRecords;
while FCounter > 0 do
ProcessMessages;
// In ProcessMessages I keep the main thread alive
ProcessRecordsContinue;
// In ProcessRecordsContinue method I process the results of background tasks and OnRequestDone method
end
else
TerminateBackgroundWorker;
end;
procedure ProcessMessages;
var
Msg: TMsg;
begin
while integer(PeekMessage(Msg, 0, 0, 0, PM_REMOVE)) <> 0 do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
constructor TEntityIndexer.Create;
begin
...
CreateBackgroundWorker;
end;
procedure TEntityIndexer.CreateBackgroundWorker;
begin
FBackgroundWorker := Parallel.BackgroundWorker
.NumTasks(INITasksCount)
.Initialize(InitializeTask)
.Finalize(FinalizeTask)
.OnRequestDone(HandleRequestDone)
.Execute(ProcessSupportStrings);
end;
procedure TEntityIndexer.FinalizeTask(const taskState: TOmniValue);
var
_obj: TObject;
begin
if not(taskState.IsObject) then
Exit;
_obj := taskState.AsObject;
if _obj is TServerSessionApp then
TServerSessionApp(_obj).ParentApplication.Free;
CoUninitialize;
end;
procedure TEntityIndexer.ProcessRecordsContinue;
begin
if FStack.Count = 0 then
Exit;
...
FStack.Clear;
StartReindex;
end;
procedure TEntityIndexer.ProcessRecords;
...
begin
FVTable.First;
while not FVTable.Eof do
begin
...
_omniValue := TOmniValue.CreateNamed(
[ovIdKey, _id,
ovXMLKey, FVTable.FieldByName('mx').AsString,
ovGenKey, FVTable.FieldByName('created').AsString
]);
FBackgroundWorker.Schedule(FBackgroundWorker.CreateWorkItem(_omniValue));
Inc(FCounter);
FVTable.Next;
end;
end;
procedure TEntityIndexer.ProcessSupportStrings(const workItem: IOmniWorkItem);
var
...
begin
if not(workItem.taskState.IsObject) then
...
if not workItem.Data.IsArray then
raise Exception.Create('Empty parameters!');
...
// make some JSON and XML strings
...
try
try
workItem.Result := TOmniValue.CreateNamed(
[... ]);
...
end;
procedure TEntityIndexer.HandleRequestDone(const Sender: IOmniBackgroundWorker;
const workItem: IOmniWorkItem);
var
...
begin
Dec(FCounter);
if workItem.IsExceptional then
begin
// Process the exception
end
else if workItem.Result.IsArray then
begin
...
FStack.AddToStack(_stackItem);
end;
end;
procedure TEntityIndexer.InitializeTask(var taskState: TOmniValue);
begin
CoInitialize(nil);
taskState.AsObject := CreateAnotherServerSession;
end;
procedure TEntityIndexer.TerminateBackgroundWorker;
begin
// Here is s problem - Termination of the BackgroundWorker doesn't work, but finalization
// of background tasks is done
FBackgroundWorker.Terminate(INFINITE);
FBackgroundWorker := nil;
end;
end.
您的任務中的代碼響應取消令牌的位置在哪裏? –
我打算繼續。我們需要看到後臺工作者正在執行的代碼能夠回答這個問題。請[編輯]您的問題以包含此代碼。 –
我只是一個平行編程和OTL的初學者,我很困惑,所以我嘗試添加與CancelAll行,我忘了刪除它。但是沒有更多的代碼來響應取消令牌。在這本書(與OTL並行編程)中,沒有提到我必須添加特殊代碼來取消任務,當我想在沒有任何條件的情況下全部停止它們時。但是,當我刪除該行問題仍在繼續。 –