2009-08-31 85 views
0

我有一個抓取另一個桌面快照的應用程序。這個過程被放置並在一個單獨的後臺工作線程中異步運行。在DoWork的事件的微小的樣機是:C#多線程:微線程睡眠開銷

private void GrabImage_DoWork(object sender, DoWorkEventArgs e) 
{ 
/*Grab the image..*/ 
System.Threading.Thread.Sleep(10) 
} 

目前,被放置在了Thread.Sleep(10),我只是想知道這麼小的睡眠是否會真正渲染表現不佳,由於恆額外不必要的上下文切換。

讓我知道這個問題是否需要進一步解釋。 乾杯,

編輯: 決定拋出一堆更多的上下文,以幫助專注於特定的答案。

問題帶來了 問:這是當前正在運行的唯一後臺線程嗎? 答:沒有。實際上有一些backgroundworker線程以及一個使用.NET Threadpool類排隊多個線程的線程。因此,睡眠最初被放入代碼中,以考慮允許這些其他線程發生上下文切換。 但是我相信無論如何操作系統是時間片的,所以我確定沒有睡眠時其他線程將有機會執行?

問:這個後臺工作人員是否在不停地運行? 答:應用程序提供了一個界面,通過切換按鈕與桌面進行交互以顯示背景圖像。 因此,如果按鈕被切換,背景工作者基本上可以關閉或不斷攪動。

我希望整體的問題對性能看起來並不重要。我試圖在性能和可用性之間找到一個很好的平衡點。

+0

Windows對各種調度程序具有默認量程,最小值爲〜10-40ms,具體取決於哪一個正在運行。 – user7116 2009-08-31 17:29:41

+0

我想另外一個想法是: 因爲我已經使用了Threadpool類,所以也要將這個工作負載排隊到線程池類而不是sepearte backgroundworker。 – Setheron 2009-08-31 17:51:59

回答

4

睡眠可能會導致額外的上下文切換,因爲它會允許其他線程在您的進程中執行。

但是,它聽起來像你有一個單一的後臺工作線程。如果是這樣的話,你可能會得到上下文切換。隨着後臺工作人員報告進度,這種情況往往會發生(因爲他們在跨線程調用)。有一個,我懷疑你會注意到涉及性能問題,但唯一可以肯定的方法是分析你的應用程序。

我最大的問題是:爲什麼你首先在這裏添加這個睡眠,特別是如果它是你擔心的事情。通常,你會在這裏專門添加一個睡眠,以允許其他線程工作,這通常會導致上下文切換。如果你是通過設計來做這件事的話,那麼這件事就不用擔心了。如果你沒有需要這個睡眠,另一方面,沒有理由包含它。


編輯:這裏有一些細節在回答您的編輯:

問:這是當前正在運行的唯一後臺線程?答:沒有。實際上有一些backgroundworker線程以及一個使用.NET Threadpool類排隊多個線程的線程。因此,睡眠最初被放入代碼中,以考慮允許這些其他線程發生上下文切換。然而,我相信無論如何,操作系統是時間片的,所以我確信沒有睡眠,其他線程將有機會執行?

操作系統將時間片,但(默認情況下)此線程將具有默認優先級。理論上講,它應該獲得與主線程和其他線程一樣多的處理器時間。你不必睡覺,但有時這是有利的(見下文)。

問:這個後臺工作人員是否在不停地運行?答:應用程序提供了一個界面,通過切換按鈕與桌面進行交互以顯示背景圖像。因此,如果按鈕被切換,背景工作者基本上可以關閉或不斷攪動。

如果工作線程將被坐在一個循環,只是不斷地吃CPU,它通常是有利的,增加一些機制,以防止它使用了整個CPU核心(除非你需要在實時性能那個線程)。一個小小的睡眠(儘管睡眠(0)同樣適用於此)是一個簡單的選擇。但是,如果算法對此有意義,那麼通常會使用某種類型的WaitHandle,以便您只在需要時進行工作。這真的取決於算法。

因爲我已經使用了Threadpool類,所以也要將這個工作負載排隊到線程池類而不是sepearte backgroundworker。

BackgroundWorker類使用ThreadPool線程,所以這樣做沒有真正的優勢。但是,BackgroundWorker使得在UI線程上工作變得更加簡單,因此,如果您在UI上顯示進度,則可以使用BW來做到這一點,就像您現在所做的那樣。

+0

我編輯了原文,並希望根據您的回覆提供一些有意義的附註。 – Setheron 2009-08-31 17:50:52

+0

我剛剛回復了您的每個編輯。 – 2009-08-31 17:59:40

+0

非常有幫助。 不知道Backgroundworker使用線程池線程。 – Setheron 2009-08-31 18:23:07

1

它絕對可以,但這一切都取決於執行此代碼的上下文。回答您的問題的最佳方法是對應用程序進行配置以查看此代碼是否會造成瓶頸。

+0

我從來沒有做過任何分析。 有沒有一個很好的指導/教程,你可以推薦。 – Setheron 2009-08-31 16:49:52

+0

查看此鏈接http://www.red-gate.com/products/ants_performance_profiler/index.htm。雖然Regate的ANTS可能要花錢,但它確實是一個出色的分析器,他們的網站可能會幫助你開始。 – 2009-08-31 17:05:24

0

使用睡眠:

  • 可能會增加總CPU時間(因爲去所需的開銷的睡眠和喚醒)
  • 會增加任務的牆/時鐘時間(因爲要去睡覺即使沒有必要)

另一種方法可能是使用較低優先級的線程而不是睡眠。

0

爲什麼需要睡覺?如果你讓線程只睡一次要同步,同步機制將是不可預知的,並且應該變得更健壯以容忍網絡延遲的巨大變化。

所有對Thread.Sleep(int)的調用都會導致上下文切換。由於Windows是一個桌面計算操作系統,調度粒度非常好,可以提高感知響應能力,但是經驗法則是10-20毫秒,這相當長。

如果快照抓取方法沒有經常運行,那麼根本沒有性能開銷,而是允許系統的其餘部分保持響應,因爲您會讓其他線程準備運行時產生CPU時間。如果你不想讓你的CPU片斷,請改用Thread.SpinWait(int)。爲了反覆調用Thread.Sleep(int)等待另一個操作完成,我建議使用至少20毫秒的休眠間隔以確保其他線程/進程確實有時間完成其工作。