如果最后一个为我抽象了踩踏管理网,为什么我会决定直接使用 System.Threading 而不是 BackgroundWorker?
我看不到无法使用 BackgroundWorker 替换 System.Threading 的情况
如果最后一个为我抽象了踩踏管理网,为什么我会决定直接使用 System.Threading 而不是 BackgroundWorker?
我看不到无法使用 BackgroundWorker 替换 System.Threading 的情况
BackgroundWorker
自 .NET 2.0 以来一直存在,旨在帮助编写将在后台线程中运行且不会阻塞 UI 线程的代码。它最初出现在 Windows 窗体中,但也适用于 WPF 或任何未来的注册同步上下文的 UI 框架。它允许您将进度和结果报告回 UI 线程,而无需处理InvokeRequired
/BeginInvoke
还支持取消。
任务并行库 (TPL) 是在 .NET 4 中引入的,旨在为异步任务建模。这些任务是异步的,可能会也可能不会在另一个线程上运行。不在另一个线程上运行的示例是异步 IO 和需要在 UI 上运行的任务(同时仍然是异步的)。此任务隐喻还支持期货(或延续),以便您可以将任务与 链接在一起ContinueWith
,有时使用特定的同步上下文,以便您可以执行诸如在 UI 线程上运行任务(例如更新 UI)之类的事情。
任务还支持取消,多个任务可以共享一个取消令牌,因此请求的取消会取消多个任务。
区别之一是Task
没有将进度报告回 UI 的固有方法。当然这是可能的,但它不是内置在接口中的。 Task
s 也支持取消。
如果您只想在后台做一件事,并且特别想与 UI 进行交流,例如报告进度,我建议您使用BackgroundWorker
. 否则,我通常建议使用Task<T>
(或者Task
如果不需要结果)。 Task
在 C# 5 async/await 语法中固有地使用...
我希望您尝试考虑每种方法的意图。
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 的复杂性。
我有一篇关于这个主题的博文。
简而言之,async Task
如果可能的话,你应该使用 s。Thread
确实提供了一些额外的“旋钮” - 例如Priority
- 但通常这些旋钮不是必需的,并且程序员经常以错误的方式转动它们。
一方面,您不能在 BackgroundWorker 上设置调度优先级,但可以在 Thread 上设置。
对我的回答提出质疑的评论继续参考 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 线程的优先级,但在工作开始后更改线程的优先级显然是不一样的。