2011-03-29 46 views
3

很多時候,當我看到一些多線程代碼時,我在代碼中看到Thread.Sleep()語句。在多線程應用程序中使用Thread.Sleep的原因是什麼?

我甚至沒有崩潰,我試圖找出問題,這樣評價了大部分的多線程代碼,並慢慢把它和最後一塊時,我增加了一個像聲明:

for (int i = 0; i < 1000000; ++i) 
    ++i; 

它沒有崩潰。所以現在我把它取代Thread.Sleep(),它似乎工作。我無法輕易地將它發佈到這裏,但是正在使用Thread.Sleep()對於多線程應用程序是必需的嗎?

他們的目的是什麼?如果不使用會導致意想不到的結果嗎?

編輯:順便說一句我正在使用BackgroundWorker,只在那裏實現我的東西,但不知道是什麼原因造成的。雖然我使用的API是應用程序不是多線程的託管應用程序。因此,舉例來說,我認爲我不能一次在多個線程上調用它的API函數。不確定,但那是我的猜測。

+3

參見[Thread.sleep代碼是一個設計不當的程序的標誌(http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-睡眠是-A-籤的-A-設計拙劣的-program.aspx)。 – Alex 2011-03-29 18:29:14

回答

4

通常,Thread.Sleep表示設計不好。話雖這麼說,它比100%的CPU核心時間更好,這正是上面的for循環所做的。

更好的選項通常是使用WaitHandle(如ManualResetEvent)在發生「事件」(這是延遲原因)時觸發線程執行的繼續。另外,在很多情況下,使用Timer也可以。

+0

謝謝里德,你可以用BackgroundWorker做這些嗎? – 2011-03-29 18:35:27

+0

@Joan:WaitHandles和BW一起工作良好 - BW仍然只是使用ThreadPool線程來完成工作,所以任何同步選項仍然有效。 – 2011-03-29 18:36:23

+0

謝謝里德,這很有道理。但最終這種拖延是無法避免的,對吧? – 2011-03-29 19:02:18

3

Thread.Sleep(1)允許切換到執行另一個線程。所以如果你有更多的線程比核心/處理器,並且你知道「現在我在這個線程中做了很多工作,下一步工作可以稍後完成」,你可以撥打Thread.Sleep(1),並允許另一個線程比本機更快地完成一些工作切換器將「暫停」當前執行的線程。

+1

'Thread.Sleep(0)'應該具有相同的效果,而不會阻塞整個ms。 – Davy8 2011-03-29 18:40:31

+0

@ Davy8你是對的。 – TcKs 2011-03-30 09:11:39

1

試試這個:編寫一個啓動100個線程的程序,並將每個線程放到for循環中,如上所述。然後編寫另一個啓動100個線程並使用Thread.Sleep代替。

運行它們並比較CPU使用率。你會看到這一點。 =)

1

Thread.Sleep()只是簡單地導致正在執行的線程暫停指定的持續時間。

我見過很多開發人員使用Thread.Sleep(),因爲他們不太可能處理依賴線程的連接。他們只是使用Thread.Sleep()來強制一個線程等待一段時間,直到認爲他們的其他線程已經完成並且他們的數據可用。

如果你有兩個線程需要彼此等待以繼續進行處理,那麼你應該真的使用.NET中內置的機制來處理類似的情況(即ManualResetEvent等)

1

Thread.Sleep()可以在某些情況下使用,例如。看門狗線程。

然而在你的情況下,它可能不是其他人指出的最佳解決方案。

沒有代碼示例,很難說,但根據您的描述,我認爲這不是Thread.Sleep()的問題。我懷疑你可能正在遭受競爭狀態 - 這通常就是爲什麼你會遇到「隨機」的錯誤行爲,甚至是多線程代碼中的「隨機」崩潰 - 這似乎是你正在經歷的。

無論出於何種原因,您的for-loop可能會導致競爭條件的微妙關鍵時刻不經常發生,但它不會解決根本原因。在進行多線程編程時有許多缺陷需要注意,如果您想避免這些,我只能建議您閱讀該主題。

我會建議你閱讀http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X

相關問題