2

如果最后一个为我抽象了踩踏管理网,为什么我会决定直接使用 System.Threading 而不是 BackgroundWorker?

我看不到无法使用 BackgroundWorker 替换 System.Threading 的情况

4

4 回答 4

7

BackgroundWorker自 .NET 2.0 以来一直存在,旨在帮助编写将在后台线程中运行且不会阻塞 UI 线程的代码。它最初出现在 Windows 窗体中,但也适用于 WPF 或任何未来的注册同步上下文的 UI 框架。它允许您将进度和结果报告回 UI 线程,而无需处理InvokeRequired/BeginInvoke还支持取消。

任务并行库 (TPL) 是在 .NET 4 中引入的,旨在为异步任务建模。这些任务是异步的,可能会也可能不会在另一个线程上运行。不在另一个线程上运行的示例是异步 IO 和需要在 UI 上运行的任务(同时仍然是异步的)。此任务隐喻还支持期货(或延续),以便您可以将任务与 链接在一起ContinueWith,有时使用特定的同步上下文,以便您可以执行诸如在 UI 线程上运行任务(例如更新 UI)之类的事情。

任务还支持取消,多个任务可以共享一个取消令牌,因此请求的取消会取消多个任务。

区别之一是Task没有将进度报告回 UI 的固有方法。当然这是可能的,但它不是内置在接口中的。 Tasks 也支持取消。

如果您只想在后台做一件事,并且特别想与 UI 进行交流,例如报告进度,我建议您使用BackgroundWorker. 否则,我通常建议使用Task<T>(或者Task如果不需要结果)。 Task在 C# 5 async/await 语法中固有地使用...

于 2012-09-13T02:21:05.730 回答
3

我希望您尝试考虑每种方法的意图。

BackgroundWorker 一开始主要是为 Windows 窗体设计的(虽然它也可以在 WPF 中使用),它只提供了一些异步操作的功能。与 System.Threading 下的所有类相比,您可以看到 BackgroundWorker 显然是建立在它们之上的。

使用 System.Threading 下的所有类,您可以构建自己的 BackgroundWorker 并享受更多功能和对代码的控制。这里的困难是尖锐的学习曲线和调试挑​​战。

所以如果你觉得 BackgroundWorker 就够用了,继续用吧。如果您发现缺少某些东西,System.Threading 中的构建块可以成为您的帮手。

在 .NET Framework 4 中,微软在 System.Threading 上设计了另一组类,命名为基于任务的异步模式,

http://www.microsoft.com/en-us/download/details.aspx?id=19957

使用它,您几乎可以忘记 BackgroundWorker,因为它提供了更多功能并为您提供了足够的控制权,同时不需要您深入研究直接使用 System.Threading 的复杂性。

于 2012-09-13T02:12:39.870 回答
2

我有一篇关于这个主题的博文

简而言之,async Task如果可能的话,你应该使用 s。Thread确实提供了一些额外的“旋钮” - 例如Priority- 但通常这些旋钮不是必需的,并且程序员经常以错误的方式转动它们。

于 2012-09-13T02:50:09.463 回答
0

一方面,您不能在 BackgroundWorker 上设置调度优先级,但可以在 Thread 上设置。

Thread.Priority 属性

对我的回答提出质疑的评论继续参考 Task 和 ThreadPool。所述问题与 Task 或 ThreadPool 无关,我的回答也不是。

请参阅上面链接中的代码示例。它清楚地演示了在启动线程之前分配优先级并控制启动线程。

完整的代码示例:

PriorityTest priorityTest = new PriorityTest();
ThreadStart startDelegate =  new ThreadStart(priorityTest.ThreadMethod);

Thread threadOne = new Thread(startDelegate);
threadOne.Name = "ThreadOne";
Thread threadTwo = new Thread(startDelegate);
threadTwo.Name = "ThreadTwo";

threadTwo.Priority = ThreadPriority.BelowNormal;
threadOne.Start();
threadTwo.Start();

// Allow counting for 10 seconds.
Thread.Sleep(10000);
priorityTest.LoopSwitch = false;

我对此进行了测试,ThreadTwo 在 ThreadPriority.BelowNormal 上开始和结束。在我的测试中,threadOne 处理大约 10X 作为 threadTwo。

BackGroundWorker 没有 Priority 属性。BackgroundWorker 以默认的 Normal 优先级启动。在 DoWork 中可以更改 BackgroundWorker 线程的优先级,但在工作开始后更改线程的优先级显然是不一样的。

于 2012-09-13T02:02:42.163 回答