C# 使用进度报告运行多个任务

C# 使用进度报告运行多个任务,c#,multithreading,winforms,c#-4.0,C#,Multithreading,Winforms,C# 4.0,我在.NET4中继承了一个Winforms应用程序(我无法更改)。应用程序使用TPL并行运行多个任务。首先,创建一个任务,并从该任务中生成更多执行复杂计算的任务。主任务正在等待WaitAll(任务) 问题是这些小计算任务向主窗体报告进度,在每个进度报告中,应用程序调用BeginInvoke()来更新进度条,但只有在所有任务完成后才会更新进度条。我认为问题在于主任务在UI线程上运行,通过调用WaitAll()它会阻塞该线程,因此BeginInvoke()调用会堆积在事件循环上 在这种情况下,正确的

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

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

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


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

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

正确的方法取决于需要执行WaitAll()的原因。但是,我认为在大多数情况下,使用后台线程等待所有任务结束应该是可行的。我需要等待所有任务,因为我需要在主任务完成后做更多的事情(它有ContinueWith()调用)。然后使用后台工作线程。例如,一种方法就像Kev的答案所建议的那样。(虽然Microsoft针对.NET 4.x确认了TaskCreationOptions.LongRunning的这种行为,但不能保证将来的.NET版本会有这种行为。不过,由于这是一个“已确认的实施细节”,所以这种行为不太可能改变;-))我尝试了所有建议的解决方案,最后使用了BackgroundWorker。它工作得很好。谢谢大家。事实上我试过了,但没用。该任务仍在主线程上运行。尽管我尽了很大努力,但实际上无法使任务与我在计算机上创建的示例应用程序中的ui线程在同一线程上运行。里奇·纽曼(Rich Newman)在他的网站上有一个样本,这可能就是你想要的。在我的例子中,它总是在UI线程上运行。我厌倦了更改选项和调度程序,但它在UI线程上运行。