全部,我已成功使用Thread
和BackgroundWorker
类来促进一些小规模应用程序的流畅UI。我最近得到了将大量代码从串口转换为多线程的工作,由于我在这个网站上看到的一些评论,我有一些问题。我必须转换的代码对SQL Server进行不同数量(通常是大量)的调用,这些SQL查询有时可以运行30分钟左右。因此,需要多线程。
我已经使用BackgroundWorker
设置了一个测试程序,这些程序运行良好。但是,有人说由于BackgroundWorker
使用线程池,它们不应该用于长时间运行的任务。我没有在任何地方读过这篇文章(即Joesph Albahari C#4.0 in a Nutshell ),这与MSDN相矛盾。我是否应该将BackgroundWorker
或Thread
用于此类目的?
提前致谢。
答案 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上的进度条更容易。但是,如果您没有显示查询的进度,那么这是使用专用线程的另一个原因。