如果最后一个为我抽象了踩踏管理网,为什么我会决定直接使用 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 的固有方法。当然这是可能的,但它不是内置在接口中的。 Tasks 也支持取消。
如果您只想在后台做一件事,并且特别想与 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 线程的优先级,但在工作开始后更改线程的优先级显然是不一样的。