You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在OmniThreadLibrary的Parallel.ForEach中接收单个任务完成的通知

如何在OmniThreadLibrary的Parallel.ForEach中接收单个任务完成的通知

看起来你现在的问题是把消息发送逻辑放在了所有任务执行完毕的环节,所以才只会收到一次最终通知。其实要实现单个任务完成就触发通知,很简单——只需要把消息发送的代码放到每个任务的执行过程内部即可。

你的Parallel.ForEach的Execute方法里,每个任务都会单独执行那个匿名函数,我们可以在每个任务完成自身工作(创建好TTransaction)之后,立刻通过当前任务的Comm通道发送消息给主线程,这样每个任务结束时都会触发一次你的MSGNewData处理函数。

修改后的代码示例如下:

procedure TfrmForEachOutput.ProcessTransactions(input: TList<TSSRINTBWTH>; output: TList<TTransaction>);
var
  outQueue   : IOmniBlockingCollection;
  transaction: TOmniValue;
begin
  outQueue := TOmniBlockingCollection.Create;
  Parallel.ForEach(0, input.Count - 1)
    .TaskConfig(Parallel.TaskConfig.OnMessage(Self))
    .NoWait
    .Into(outQueue)
    .Execute(
      procedure(const task: IOmniTask; const value: integer; var result: TOmniValue)
      begin
        result := TTransaction.Create(input[value], task);
        // 每个任务完成后立即发送通知
        task.Comm.Send(MSG_NEWDATA, Format('索引 %d 的任务已完成', [value]));
      end
    );

  for transaction in outQueue do
  begin
    output.Add(transaction.AsObject as TTransaction);
  end;
end;

你还可以调整MSGNewData处理函数,方便直观看到具体是哪个任务完成了:

procedure TfrmForEachOutput.MSGNewData(var msg: TOmniMessage);
begin
  OutputDebugString(PChar(Format('收到任务完成通知:%s', [msg.MsgData.AsString])));
end;

这里的核心逻辑是:每个任务实例(task: IOmniTask)都自带线程安全的通信通道Comm,通过它发送的消息会被你在TaskConfig里指定的接收者(也就是你的窗体Self)处理,而且是每个任务完成就立刻发送,不会等到所有任务都结束。

如果需要在消息里传递更复杂的数据,也可以用TOmniValue封装,它能安全地跨线程传递各种类型的数据,避免线程安全问题。

备注:内容来源于stack exchange,提问作者chang long

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.17 12:37:57