我应该使用BackgroundWorker或Threads吗?

时间:2011-10-11 12:39:11

标签: c# multithreading

全部,我已成功使用ThreadBackgroundWorker类来促进一些小规模应用程序的流畅UI。我最近得到了将大量代码从串口转换为多线程的工作,由于我在这个网站上看到的一些评论,我有一些问题。我必须转换的代码对SQL Server进行不同数量(通常是大量)的调用,这些SQL查询有时可以运行30分钟左右。因此,需要多线程。

我已经使用BackgroundWorker设置了一个测试程序,这些程序运行良好。但是,有人说由于BackgroundWorker使用线程池,它们不应该用于长时间运行的任务。我没有在任何地方读过这篇文章(即Joesph Albahari C#4.0 in a Nutshell ),这与MSDN相矛盾。我是否应该将BackgroundWorkerThread用于此类目的?

提前致谢。

4 个答案:

答案 0 :(得分:5)

答案 1 :(得分:3)

线程池背后的想法是它重用线程,从而分摊创建新线程的成本。创建线程可能是一个非常昂贵的操作,因此如果可能的话,重用线程是有意义的。如果在线程池上安排长时间运行的作业,则强制它创建其他线程,从而降低重用线程的好处。

答案 2 :(得分:2)

BackgroundWorker适合用于长时间运行的任务。来自ThreadPool的线程不应该用于长时间运行的任务(BackgroundWorker不使用线程池线程。)

此外,30分钟的SQL查询绝对是代码味道。你可能想调查一下那里发生了什么,看看你是否可以加快速度。

编辑:我错了 - BackgroundWorker 使用线程池线程。我将把这个答案留给下面的讨论。

答案 3 :(得分:1)

ThreadPool具有最大活动线程数(GetMaxThreads / SetMaxThreads)。超过该数字的任何任务将保持排队,直到ThreadPool线程可用。出于此示例的目的,假设最大线程数为10.如果通过BackgroundWorker生成10个查询,并且每个查询在30分钟内完成,则ThreadPool上排队的任何其他任务将不会跑到30分钟后。

该任务可能只是来自更新UI上的时钟的Timer的微不足道的刻度。这可能会有问题,因为该时钟可能会被卡住半小时,直到线程可用。实际上,MaxThreads肯定大于10.我的是1023(.NET 4,2x2.26GHz笔记本电脑)。所以,如果你决定坚持使用BackgroundWorker,希望你不会遇到这个问题。仍然有用的是理解为什么通常不建议在ThreadPool上执行长时间运行的任务。

就个人而言,我只是为了安全而使用专用线程。特别是因为线程在等待查询完成时肯定会处于空闲状态。我在您的案例中使用BackgroundWorker看到的唯一优势是更新UI上的进度条更容易。但是,如果您没有显示查询的进度,那么这是使用专用线程的另一个原因。