gpt4 book ai didi

delphi - 使用取消和终止处理程序正确构建 ParallelTask​​ (IOmniParallelTask​​)

转载 作者:行者123 更新时间:2023-12-03 15:56:10 25 4
gpt4 key购买 nike

我只是在阅读文档后尝试使用 OmniThreadLibrary,但在构建 ParallelTask​​ 时我仍然面临一些简单/早期的问题。

使用 cancellationTokenterminationHandler 构造 ParallelTask​​ 后,terminationHandler.OnTermulatedOnStop 不会被执行异步执行完成后执行,但我无法找出原因:-(

我希望一些 OTL 专业人士可以帮助我解决这个问题。

我想要实现的目标:

  • 执行异步操作
  • 取消时停止执行(cancellationtoken)
  • 异步操作完成后在主线程中执行一些代码(检查异常)

到目前为止我做了什么:

阅读文档后,我创建了一个 ParallelTask​​,通过 TaskConfig 设置 cancellationTokenterminationHandler 并执行操作。执行的操作本身会检查发出信号的 cancellationToken 并执行其工作(此处为 1 秒的 sleep )。 HandleOnTermminate 方法检查错误并设置 fIsDone 和 fHasError 标志,由主线程中的某人读取。

unit OTLSetup.Async;

interface

uses
OtlParallel, OtlSync, OtlTaskControl, OtlTask;

type
IAsyncOperation = interface
['{6B10AB46-DEB6-48F5-AC36-E9327AA54C82}']
procedure Execute;
procedure Cancel;

function IsDone: boolean;
end;

TAsyncOperation = class(TInterfacedObject, IAsyncOperation)
protected
fParallelTask: IOmniParallelTask;
fCancellationToken: IOmniCancellationToken;
fIsDone: boolean;

procedure HandleOnTerminated(const task: IOmniTaskControl);
procedure HandleOnStop;
procedure AsyncOperation(const task: IOmniTask);
public
procedure Execute;
procedure Cancel;

function IsDone: boolean;
end;

implementation

uses
Winapi.Windows;

{ TAsyncOperation }

procedure TAsyncOperation.Cancel;
begin
fCancellationToken.Signal;
end;

procedure TAsyncOperation.Execute;
begin
if Assigned(fParallelTask) then
Exit;

fIsDone := false;
fCancellationToken := CreateOmniCancellationToken;
fParallelTask := Parallel.ParallelTask;
fParallelTask.NoWait.NumTasks(1);
fParallelTask.TaskConfig(Parallel.TaskConfig.CancelWith(fCancellationToken).OnTerminated(HandleOnTerminated));
fParallelTask.OnStop(HandleOnStop);
fParallelTask.Execute(AsyncOperation);
end;

procedure TAsyncOperation.AsyncOperation(const task: IOmniTask);
var
I: Integer;
begin
for I := 0 to 5 do
if task.CancellationToken.IsSignalled then
Exit
else
Winapi.Windows.Sleep(1000);
end;

procedure TAsyncOperation.HandleOnStop;
begin
fParallelTask := nil;
fIsDone := true;
end;

procedure TAsyncOperation.HandleOnTerminated(const task: IOmniTaskControl);
begin
fParallelTask := NIL;
fIsDone := true;
end;

function TAsyncOperation.IsDone: boolean;
begin
result := fIsDone;
end;

end.

有了这种和平的代码,fIsDone 永远不会被设置,因为 HandleOnTerminateHandleOnStop 永远不会被调用。所以上面的例子下面的 ConsoleApplication 似乎永远不会结束:

program OTLSetup;

{$APPTYPE CONSOLE}

{$R *.res}

uses
System.SysUtils,
OTLSetup.Async in 'OTLSetup.Async.pas';

var
LAsync: IAsyncOperation;
begin
LAsync := TAsyncOperation.Create;
try
LAsync.Execute;

while not LAsync.IsDone do
Writeln('Async task still running');

Writeln('Async task finished');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

最佳答案

正如评论中所发布的,我面临的问题是由控制台应用程序本身引起的,因为它不包含消息循环(在我的例子中是 DUnitX 项目)。

由于 OTL 通信似乎基于 windowsmessages,因此在没有工作消息循环的情况下不会触发 OnTermulated 和 OnStop。

关于delphi - 使用取消和终止处理程序正确构建 ParallelTask​​ (IOmniParallelTask​​),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34024094/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com