2014-09-30 88 views
1

我很好奇Thread.Sleep是如何實現的。我使用Reflector查看了Thread.Sleep的實現。它調用以下功能:Thread.Sleep執行

[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical] 
private static extern void SleepInternal(int millisecondsTimeout); 

有沒有人知道它在哪裏定義?我知道其他的選擇,比如Task.Delay。但對實際的實施細節很好奇。

+1

'睡眠()'使線程睡眠。如果您希望線程「做其他事情」並在n毫秒後報告給您,請查看定時器。 – John3136 2014-09-30 01:43:48

+0

當它醒來時,線程可以繼續工作。在離開線程睡覺類似於人類睡覺。 [extern](http://msdn.microsoft.com/en-us/library/e59b22c5.aspx)方法是在外部實現的,在這種情況下,它是由.NET框架提供的黑盒子(反過來框架將調用適當的本地功能,如[WinAPI睡眠](http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v = vs.85).aspx)或什麼)。 – user2864740 2014-09-30 01:47:43

+0

@ John3136我知道其他的選擇,比如Task.Delay。但是對於實際的實現細節感到好奇 – 2014-09-30 02:09:09

回答

3

Joe Duffy的書Concurrent Programming提供了所有你需要的細節。但總結:

  • Thread.Sleep行爲類似於贏API函數SleepEx
  • 持續時間參數= 0將導致當前線程屈服於具有相同或更高優先級的線程。
  • 持續時間參數> 0將導致上下文切換,並且當前線程將保持等待狀態,直到經過指定的時間量(大約)。
  • 線程將保持在可警告狀態,這意味着它允許通過QueueUserAPC處理APC方法,並將響應Thread.Interrupt調用。

爲了更完整地理解它的實現方式,我建議通過查看SSCLI代碼。

關於你不能重複使用其他工作線程的問題......我有點困惑。 Thread.Sleep是一個自願暫停,所以你(程序員)告訴線程不要做更多的工作。就像我之前提到的那樣,線程被認爲是可警告的,所以你可以實際上打斷它,甚至強迫它通過APC方法來工作。

有關使.NET線程運行APC而Thread.Sleep仍處於掛起狀態的更多信息,請參閱此question

+0

感謝您的評論,非常有用。 – 2014-09-30 02:56:03

0

使用await Task.Delay()如果要在一個系統線程(一個真正的線程,而不是用戶線程)調用線程被重用

+0

感謝您的建議,我意識到這一點,但只是徘徊在'Thread.Sleep'的實現細節 – 2014-09-30 02:09:57

1

Thread.Sleep()是掛鉤到操作系統內核調度內部通話,類似於進程睡眠。它將執行上下文(在內核進程級別上可見)置於「睡眠」等待狀態,因此它在喚醒之前不消耗CPU。這不是一個忙碌的等待。

如果您想讓它清醒和/或做其他事情,請使用除Thread.Sleep()之外的其他一些機制。