异步方法模式与没有它的情况下如何重用线程

时间:2011-10-16 13:14:18

标签: .net multithreading .net-4.0

我正在阅读 C#简而言之4.0 - 精彩的阅读!我曾经在.NET框架上做过的最好的。

我刚刚完成第21/22/23章,我以为我对线程有所了解,但我似乎不知道:)在阅读有关AMP(异步方法模式)及其如何实现线程经济性时,我感到很惊讶,以及它与普通线程使用的比较。

底线:

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

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

2 个答案:

答案 0 :(得分:2)

对于这两个问题:

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

所以:直到你在线程中的工作没有完成,如果你使用像Monitor.Wait / Monitor.Pulse这样的等待机制,它也不会被删除/重用:)

答案 1 :(得分:2)

ManagedThreadId在执行线程期间是常量。正如MSDN上所写

  

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

ProcessThread.Id可以改变。您可以通过Getting the thread ID from a thread之类的代码恢复它,例如通过AppDomain.GetCurrentThreadId

我要补充一点,你认为对于作为光纤执行的线程可能是真的。有一个计划让SQL Server使用光纤执行CLR“托管”代码(当时SQL Server确实使用了光纤)。有些项目使CLR光纤兼容。最后我认为这个项目已被删除,但仍然有迹象(如ManagedThreadId与操作系统线程ID“不同”(去年我研究过很多,如果有可能在C#中使用光纤)答案是否定的:-))

来自Fibers and the CLR

的引用
  

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

  

也许我们在本质上支持纤维方面做了最大的事情   运行时是将CLR线程对象与物理OS分离   线程。