Dan*_*Dan 2 delphi omnithreadlibrary delphi-xe4
使用OmniThreadLibrary和Delphi XE4,我希望运行多个在后台处理数据的线程,为我现有的代码增加速度.
调用下面的过程时,Application GUI将停止处理任何输入,直到所有线程都完成为止.我的理解是,.NoWait即使线程正在运行,using也应允许该过程退出.
procedure Test(input: TStringList; output: TList<TMaintFore>);
var
outQueue: IOmniBlockingCollection;
transaction: TOmniValue;
begin
outQueue := TOmniBlockingCollection.Create;
Parallel.ForEach(0, input.Count - 1)
.NoWait
.Into(outQueue)
.Execute(
procedure(const value: integer; var result: TOmniValue)
begin
result := TMaintFore.Create(input[value]);
end
);
end;
Run Code Online (Sandbox Code Playgroud)
我对ForEach循环的理解是否不正确,建议我应该使用替代方法来实现后台处理?任何关于正确使用OmniThreadLibrary的建议都表示赞赏.
gab*_*abr 10
您必须将Parallel.ForEach返回的接口存储在全局(表单等)变量中,并仅在ForEach完成执行时销毁它.
在您的示例中,ForEach的结果存储在临时变量中,该变量在Test过程退出时被销毁.ForEach析构函数等待所有任务完成并阻止您的程序.
在任务完成时销毁foreach接口的最安全(但不可否认的是非显而易见的)方法是使用OnStop方法并从中将命令排入主线程.
var
loop: IOmniParallelLoop<integer>;
loop := Parallel.ForEach(1, N).NoWait;
loop.OnStop(
procedure (const task: IOmniTask)
begin
task.Invoke(
procedure
begin
// do anything
loop := nil;
end);
end);
loop.Execute(
procedure (const value: integer)
begin
...
end);
Run Code Online (Sandbox Code Playgroud)
这在wiki中有记录.