1

背景

我有一个单元测试,我在其中检查我的处理程序代码代码在多线程压力期间是否表现良好:

procedure TestAppProgress.TestLoopedAppProgressRelease_SubThread;
begin
  var bt:=Parallel.ParallelTask.NumTasks(1).NoWait.Execute(
    procedure
    begin
      SetWin32ThreadName('TestLoopedAppProgressRelease_SubThread');
      RunLoopedAppProgressRelease;
    end
  );
  lSuccess:=bt.WaitFor(cRunLoopTimerMilliSecs*2);
  if not lSuccess then
    bt.Terminate; // emergency termination, unit test failed <<< How do I do this?
  Check(lSuccess,'Failed to finish within expected time');
end;

如果并行线程未能在预期时间内完成,则说明出现问题并且我的检查失败。不幸的是,如果并行任务挂起,它永远不会结束,并且我的单元测试会冻结,因为在我等待永无止境的并行任务完成的例程结束时释放了 bt 接口。

所以我需要以邪恶的方式关闭我的并行任务。

注意 1:这是一个单元测试,我并不真正关心线程清理:如果单元测试失败,无论如何都需要修复一些东西。我只是不希望我的整个单元测试套件挂起/冻结,而只是报告失败并继续我的套件中的下一个测试。

注意 2:Numthreads(1) 可以省略或任意数量的线程。

:如何IOmniParallel强制终止任务?

4

1 回答 1

1

好吧,我应该做更好的研究。下面是单后台线程的解决方案,使用IOmniTaskControl界面即可:

procedure TestAppProgress.TestLoopedAppProgressRelease_SubThread;
begin
  var lTask:=CreateTask(
    procedure (const aTask:IOmniTask)
    begin
      RunLoopedAppProgressRelease;
    end,
    'TestLoopedAppProgressRelease_SubThread'
  );
  lTask.Run;
  var lSuccess:=lTask.WaitFor(cRunLoopTimerMilliSecs*2);
  if not lSuccess then
    lTask.Terminate; // emergency termination, unit test failed
  Check(lSuccess,'Failed to finish within expected time');
end;

如果你想在多个子线程中运行它,你需要将它包装在一个IOmniTaskGroup

procedure TestAppProgress.TestLoopedAppProgressRelease_MultiSubThread;
const cThreads=4;
begin
  var lTaskGroup:=CreateTaskGroup;
  for var i:=1 to cThreads do
  begin
    var lTask:=CreateTask(
      procedure (const aTask:IOmniTask)
      begin
        RunLoopedAppProgressRelease;
      end,
      'TestLoopedAppProgressRelease_SubThread '+i.ToString
    );
    lTaskGroup.Add(lTask);
  end;
  lTaskGroup.RunAll;
  var lSuccess:=lTaskGroup.WaitForAll(cRunLoopTimerMilliSecs*2);
  if not lSuccess then
    lTaskGroup.TerminateAll; // emergency termination, unit test failed
  Check(lSuccess,'Failed to finish within expected time');
end;

在我的调试器中使用延迟/断点我验证了单元测试(错误)处理现在可以按预期工作。这包括由于被杀死的线程而导致的预期内存泄漏。

我仍然觉得IOmniParallelTask应该有一个Terminate类似于和中的IOmniTask方法IOmniTaskGroup

于 2020-06-30T20:32:12.853 回答