我想使用任务并行库来执行一些计算密集型任务,但是有一位同事告诉我,IIS创建工作线程的开销很大。
当你调用Task.Factory.StartNew()时,我不确定做了什么...说100次。 IIS如何处理这个问题?这是一个巨大的风险,还是有办法使这个应用程序非常有用?
答案 0 :(得分:1)
First Tasks!=主题。您可能有很多任务由少数线程(已经被池化)提供服务。
作为一般规则,我反对在Web服务器上运行长时间运行的进程。保持长时间运行的工作存在大量问题,并且您倾向于降低Web服务器的可伸缩性,特别是如果您正在对长时间运行的cpu密集型作业进行并列化。不要忘记在机器上运行的最佳线程数等于“逻辑”核心数。您希望避免创建多余的线程(每个托管线程在开销中吃掉类似于meg的东西)。运行cpu密集型作业会使cpu时间远离服务请求。
在我看来,在Web服务器上使用tpl的最佳方法是使用它,目的是让您尽可能地以非阻塞方式发出请求,这样可以将最大数量的请求与最小线程数。请记住,许多人决定通过高度异步请求处理获得的额外规模不值得额外的复杂性。取决于您的具体情况。
因此,简而言之,在Web服务器上运行许多长时间运行的cpu绑定任务会降低可扩展性。如果您正在使用任务,线程,后台工作者或线程池,那无关紧要。归结为同样的事情。
答案 1 :(得分:1)
Task
抽象的一个好处是它抽象创建线程。这意味着TPL(实际上,ThreadPool
)可以决定实际线程的最佳数量。因此,创建100个Task
最有可能不会创建100个Thread
。因此,您不必担心创建Thread
s。
但它也取决于它们是什么类型Task
。如果你有100 Task
个执行一些长IO绑定操作,所以它们在大多数情况下都会阻塞,这不是很好用TPL而你的代码效率很低(实际上你可能最终得到100 Thread
S)。
另一方面,如果你有100个CPU限制,相对较短的Task
,这是TPL的最佳点,你将获得良好的效率。
如果你真的关心效率,你也应该知道Task
确实有一些开销。因此,在某些情况下,将多个Task
合并为一个较大的Parallel.ForEach
以使开销更小可能是有意义的。或者您可以使用已经执行此操作的内容:Parallel.For
或Task
,如果它们适合您的用例。另一个优点是,使用它们的代码比手动使用{{1}}更具可读性。
答案 2 :(得分:0)
如何创建服务来处理这项工作呢?在缩放方面你会好得多,并且可以很好地隔离这个工作单元......即使工作是受计算限制的。
在我看来 - 不要在ASP.NET中使用Thread Pool/BackgroundWorker/Thread
。在您的情况下,TPL
只是包装线程池。它通常比它的价值更麻烦。
答案 3 :(得分:0)
任何主机的线程开销都是相同的。与IIS无关,至少在性能方面如此。
还有其他问题。例如,在应用程序关闭时,用户线程被粗暴地中止。