为什么*不*改变ThreadPool(或任务)线程的优先级?

Web和Stack Overflow中有很多地方不鼓励改变ThreadPool线程或TPL任务的优先级。特别是: “您无法控制线程池线程的状态和优先级。” “运行时管理线程池。您无法控制线程的调度,也无法更改线程的优先级。 “你不应该改变PoolThread的文化或优先级......或者就像你没有画出或重新装修租赁汽车一样。” “在某些情况下,创建和管理自己的线程而不是使用线程池线程是合适的:(例如......)您需要一个线程具有特定的优先级。” “ThreadPool中的每个线程都以默认优先级运行,而更改ThreadPriority的代码无效。” 但是,这样做很简单,调试器显示更改似乎确实存在(只要值可以回读)。
Thread.CurrentThread.Priority = ThreadPriority.AboveNormal;
所以问题是,这个禁忌的具体原因是什么? 我怀疑:这样做会扰乱游泳池的微妙负载平衡假设。但这并不能解释为什么有些消息来源说你无法改变它。     
已邀请:
线程池,特别是.NET 4.0线程池,有很多技巧,是一个相当复杂的系统。添加任务和任务调度程序以及工作窃取和各种其他事情,现实是你不知道发生了什么。线程池可能会注意到您的任务正在等待I / O并决定快速安排任务,或者暂停线程以运行更高优先级的事务。您的线程可能以某种方式成为优先级较高的线程(您可能或可能不知道)的依赖项,并最终导致死锁。您的线程可能会以某种异常方式死亡,无法恢复优先级。 如果你有一个长期运行的任务,你认为你的线程最好具有较低的优先级,那么线程池可能不适合你。虽然.NET 4.0中的算法得到了改进,但它仍然最适合用于创建新线程的成本与任务长度不成比例的短期任务。如果您的任务运行超过一两秒,则创建新线程的成本微不足道(尽管管理可能很烦人)。     
我已经完成了一个减小大小的线程池的实验,这似乎表明线程的优先级在返回池后重置为正常。这个关于线程的资源似乎证实了这一点。因此,即使你这样做,效果似乎也非常有限。     
降低优先级也可能导致意外后果。 想象一下,您在应用程序中安排任务,但也调用了一个安排其他几个任务的库。假设您在应用任务运行时降低线程优先级。然后你可以在lib中等待那个低优先级任务完成的正常优先级任务,如果池没有产生很多线程,但是低优先级线程如果剩下的那个则可能没有给它太多的CPU时间。系统有许多想要运行的普通优先级线程。 增加池线程数可以减轻这种情况,代价是在堆栈上浪费更多内存并在上下文切换上花费更多CPU时间。     
如果你真的想要,你当然可以改变它,但鉴于线程池线程被重用,下一个运行的代码可能不会期望更改。     
如果您确实更改了任何内容,请使用try / finally确保在找到它时保留它。     
它是气馁的,特别是如果你提高优先级,因为它会影响你的系统的整体性能。 不提供过于复杂的答案,但一般来说,线程优先级是一个复杂的主题。例如,Windows有2个相关的描述符:线程优先级和进程优先级。两者的范围从空闲,最低,到时间关键,最高。当您启动新进程时,它将设置为默认值,即中间范围(具有正常线程优先级的正常进程优先级)。 此外,线程优先级是相对的,这意味着即使在繁忙的系统中将线程的优先级设置为最高也不会确保它将“实时”运行。 DotNET不提供此保证,Windows也不提供保证。从那你可以看出为什么最好不要单独留下线程池,因为,99.9%的时间,它最了解:) 总而言之,如果任务涉及长时间计算,则可以降低线程的优先级。这不会影响其他进程。 但是,只应对需要快速响应并且执行时间短的任务执行优先级增加,因为这会对其他进程产生负面影响。     

要回复问题请先登录注册