【问题标题】:Is it possible to reset/reinitialize a pipeline (or BackgroundWorker) in OmniThreadLibrary?是否可以在 OmniThreadLibrary 中重置/重新初始化管道(或 BackgroundWorker)?
【发布时间】:2012-11-10 19:49:55
【问题描述】:

通过重新初始化,我的意思是停止正在运行的任务(或者甚至杀死线程,如果我必须这样做)并恢复,就好像管道/线程从来没有已初始化/已启动。

我的代码(我使用的是 delphi 2010,OmniThreadLibrary 3.02)如下所示:

procedure SomeProc();
var
   AFile : TOmniValue;
begin
     APipeline := Parallel.Pipeline.NumTasks(5).Stage(StageProc).Run;

     AFile.CreateNamed(['FileID', FileID, 'FileName', FileName]);
     MyPipeline.Input.Add(AFile);
end;
// --------------- //
procedure StageProc(const Input, Output : IOmniBlockingCollection; const Task : IOmniTask);
begin
    // ...
end;

我需要这样的东西:

// --------------- //
procedure ResetPipeline();
begin
     // Stop any task running inside StageProc() & reset pipeline, ie.
     KillTasks(pipeline);
     pipeline := nil;
end;

注意事项

  1. FWIW,是的,我完全知道这确实是个坏主意!

  2. 我也很清楚,最好的方法是向任务发送停止信号并等待它们很好地关闭,并经常检查任务内的停止信号。 我对这个非常特殊的情况不感兴趣。

  3. 虽然上面的代码只提到了管道,但是重置BackgroundWorker的解决方案对我来说就足够了。

提前致谢!

【问题讨论】:

  • 发送停止信号。喜欢大自然的意图。我希望 OTL 不会提供执行您提议的滥用行为的例程。
  • 谢谢大卫,但正如我已经所说,在这种特殊情况下我对此不感兴趣。我对杀死(或重新初始化管道)而不是很好地停止任务更感兴趣! (是的即使考虑到这种方法的失败)

标签: multithreading delphi delphi-2010 omnithreadlibrary


【解决方案1】:

免责声明:不建议强制终止线程 - 请不要在家里尝试。

我相信你可以像这样做你想做的事:

GlobalParallelPool.WaitOnTerminate_sec := 0;
GlobalParallelPool.CancelAll;

【讨论】:

  • 谢谢大卫,但恐怕既没有终止任务也没有终止线程。同样,我真的了解终止线程有多糟糕,但在我的特殊情况中,它既安全又可行..
  • 根据我对代码的阅读,这应该会导致对 TerminateThread 的大量调用。你也有代码,还有一个工作测试台。也许您可以在调试器中检查并找出那些 TerminateThread 调用不运行的原因。
  • 我做到了;它使我无处可去(另外,我不愿意更改 OTL,我不想破坏某些东西)。 Primoz(OTL 作者)aknowledged here 确实有正当理由杀死一个任务(尽管我很确定它被滥用)
  • FWIW,我终于在我的特殊情况下解决了杀死EXE(这是一个在后台运行的不可见的EXE),我不得不解决这个问题真的很遗憾如此残酷的技术,但在 OTL 允许之前,似乎没有办法在 OTL 中重置/杀死任务。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-01-20
  • 2021-06-03
  • 1970-01-01
  • 2020-10-09
相关资源
最近更新 更多