异步方法模式vs线程在没有异步方法模式的情况下如何被重用



我正在阅读 c#简而言之4.0 -很棒的阅读!这是我所见过的最好的。net框架。

我刚刚完成了第21/22/23章,我以为我知道一些关于线程,但我似乎我不:)我很惊讶当阅读AMP(异步方法模式)和它如何使线程经济,它与普通线程使用的比较。

底线:

我一直认为,如果我有一个线程,当该线程正在做某事,然后等待条件(如Monitor.Pulse)时,该线程使用的所有堆栈信息都被冻结。在等待特定条件时,线程可以被重用来服务另一个任务。基本上:一个线程可以同时执行多个代码路径。但显然我错了。所以我的问题是:

  • 当线程启动时,执行的代码总是相同的(直到代码完成,线程可以在谈论ThreadPool时被重用)?
  • 如果是这样,在执行长时间运行的任务时,如果我访问ManagedThreadId属性,我将始终获得相同的id?

对于两个问题:

ThreadPool重用不工作的线程,基本上有一个守护进程关心所有池线程:如果它们超过ThreadPool。MinThreads它们将被删除,否则当ThreadPool.QueueWorkUserItem被调用时,它们将被重用来做新的工作。

所以:直到你的工作在一个线程内还没有完成,它将不会被删除/重用,如果你正在使用等待机制,如监视器。等待/监控。脉冲:)

ManagedThreadId在线程执行期间是恒定的。写在MSDN

ManagedThreadId属性的值不随时间变化,即使托管公共语言运行库的非托管代码将线程作为一个纤维实现。

是ProcessThread。这是可以改变的。您可以通过以下代码来恢复它:例如,通过AppDomain从线程获取线程ID。GetCurrentThreadId

我要补充一点,你所认为的对于作为纤维执行的线程可能是正确的。有一个计划是让SQL Server使用光纤执行CLR"托管"代码(SQL Server当时确实使用光纤)。有一些项目是为了使CLR光纤兼容。最后,我认为这个项目被放弃了,但仍然有迹象(比如ManagedThreadId与OS线程Id"不同")(去年我研究了很多,如果有可能在c#中使用纤维。答案是否定的:-))

引用自Fibers和CLR

CLR试图在Whidbey中添加对纤维的支持。这是在响应SQL Server Yukon托管运行时进程,也就是SQLCLR。最终,主要是由于时间的压力和长期的压力与纤维模式相关的虫尾,我们举手宣布了它不支持的。

也许我们做的最大的事情来支持纤维的本质运行时将CLR线程对象与物理操作系统解耦线程。

最新更新