【问题标题】:Running multiple tasks with progress report使用进度报告运行多个任务
【发布时间】:2013-11-28 11:49:57
【问题描述】:

我在 .NET 4 中继承了一个 Winforms 应用程序(我无法更改)。该应用程序使用 TPL 并行运行多个任务。首先,创建一个任务,并从该任务生成更多执行复杂计算的任务。主要任务正在等待WaitAll(tasks)

问题是这些小计算任务向主窗体报告进度,在每个进度报告中,应用程序调用BeginInvoke() 来更新进度条,但只有在所有任务完成后才会更新。我认为问题在于主任务在 UI 线程上运行,并通过调用 WaitAll() 阻塞该线程,因此 BeginInvoke() 调用堆积在事件循环中。

在这种情况下正确的方法是什么?

阅读其他 SO 答案,我似乎无法强制任务在 ThreadPool 线程上运行,因此我倾向于用 BackgroundWorker 替换主任务。

【问题讨论】:

  • 正确的方法取决于您需要执行 WaitAll() 的原因。但是,我认为在大多数情况下,使用后台线程等待所有任务结束应该可以工作。
  • 我需要 WaitAll 因为在主任务完成时我需要做更多的事情(它有 ContinueWith() 调用)。
  • 然后使用后台工作线程。例如,一种方法就像 Kev 的回答所建议的那样。 (虽然这种行为 TaskCreationOptions.LongRunning 已由 Microsoft 为 .NET 4.x 确认,但不能保证未来 .NET 版本的行为。但话说回来,这不太可能改变,因为它是一个“确认的实现细节' ;-) )
  • 我尝试了所有建议的解决方案,最终使用了 BackgroundWorker。它完美地工作。谢谢大家。

标签: c# multithreading winforms c#-4.0


【解决方案1】:

在初始任务上设置选项 TaskCreationOptions.LongRunning 将导致它在单独的线程(不是线程池线程)上运行

【讨论】:

  • 其实我试过了,还是不行。任务仍然在主线程上运行。
  • 尽我所能,我实际上无法让任务在与我在我的机器上创建的示例应用程序中的 ui 线程相同的线程上运行。 Rich Newman 在他的网站上有一个样本,这可能是您正在寻找的。 richnewman.wordpress.com/2012/11/21/…
  • 在我的例子中,它总是在 UI 线程上运行。我厌倦了更改选项和调度程序,但它仍然在 UI 线程上运行。
猜你喜欢
  • 1970-01-01
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 2022-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多