不是主题专家我正在尝试更多地了解.NET中可用的异步世界。 Task.Run和ThreadPool.QueueUserWorkItem都允许在池线程上调度工作,但有什么区别,或者,如果您愿意,两者的优缺点是什么? 以下是我的专业人士名单。不确定它是否完整甚至是正确的。
ThreadPool.QueueUserWorkItem专业人士:
Task.Run专业人士:
答案 0 :(得分:18)
ThreadPool.QueueUserWorkItem
只是与Task.Run
(在.NET 4.5中引入)完成相同工作的旧实现(在.NET 1.1中引入)。
Microsoft试图避免破坏.NET中的向后兼容性。
为.NET 1.1编写的东西可以在.NET 4.5中编译和运行,通常没有任何更改。
中断更改通常来自编译器更改,而不是框架更改,例如the variable declared in a foreach
used inside a lambada behaving differently in C# 5 and newer。
当您拥有ThreadPool.QueueUserWorkItem
时,没有真正的理由使用Task.Run
。
一个终点:具有讽刺意味的是,事情实际上与HostingEnvironment.QueueBackgroundWorkItem(...)
完全一致。
它允许您在ASP.NET环境中的后台线程上运行某些内容,并让后台工作通知Web服务器AppDomain
关闭(在长时间不活动时经常会发生这种情况)。
答案 1 :(得分:4)
我最近意识到的ThreadPool.QueueUserWorkItem
和Task.Run
之间的一个区别是他们处理异常的方式。
如果ThreadPool.QueueUserWorkItem
内部发生了未处理的异常,并且未由全局异常处理程序处理,则它将使父线程崩溃。另一方面,在您Task.Run
或await
之前,来自Task.Wait
主题的无法处理的异常不会传播。