2009-02-07 180 views
8

我想在我正在開發的應用程序中使用.NET Backgroundworker對象。.NET Backgroundworker對象的線程優先級

所有互聯網上的材料說,這個物體在「後臺」運行,但無處我已能夠證實,這個後臺線程確實是一個「低優先級」模式運行。這個問題的產生是因爲在Windows中(我認爲)後臺任務可以以「正常」或「低於正常」或「低」優先級模式運行。

在我的應用程序,我想我自己設定的優先級DoWork的函數內通過調用 ...

Thread.CurrentThread.Priority=ThreadPriority.Lowest 

...

但這似乎沒有任何效果。背景工作者是否會忽略此調用?

我想解釋些:

我的應用程序是一個互聯網客戶端收集溫度的實時數據,從室內溼度等,並上傳到一個網頁(不是Web服務)使用

system.net.webclient.UploadValuesAsync(...)調用

我寫的應用程序,使得客戶端GUI收集來自腔中的數據,時間標記他們,然後他們排隊上傳像這樣

...

Synclock objlock 
    debug.print("Queueing reading...") 
    dataQ.Enque(reading) 
End Synclock 
... 

BackgroundWorker的的DoWork的功能出列,然後上傳這樣的...

..............

Do 
     if dataQ.count() <> 0 then 
      Synclock objlock 
       reading = dataQ.DeQue() 
      End Synclock 
      Dim client As New System.Net.WebClient 
      ...put the reading in NameValueCollection and upload to server page 
      req = new NameValueCollection 
      ... 
      ... 
      client.UploadValuesAsync(uri, "POST", req) 
     endif 
     thread.sleep(1) 'without this line the CPU usage goes upto 100% and seems to slow other tasks! 
    Loop 

..... ...........

當我運行該程序時,我發現只要調用UploadValuesAsync,打印出調試窗口就會停止。我還添加了調試語句,以便隨時查看隊列中有多少個讀數。這個任務真正在低優先級運行,我期望看到隊列數量隨着數據的採集而迅速增加,然後僅在前景空閒且數據未被採集時才減少。但這種情況並非如此。只要將讀數添加到隊列中,它就會被取出並上傳。所以隊列數總是爲1或0!

我的方法有什麼問題嗎?我應該不使用背景工作者對象嗎?

順便說一句,這是在運行Windows XP的雙核筆記本電腦。

回答

13

我想補充什麼喬恩和馬克已經說過:

後臺線程不具有較低的優先級。前臺線程和後臺線程之間的區別在於,一旦沒有前臺線程正在運行,CLR將關閉進程。線程池線程是後臺線程。

實際上,您可以設置線程池線程的優先級,但由於您幾乎無法控制哪個線程池線程將實際運行您的任務,因此建議不這樣做。如果您需要特定優先級的線程,則應使用線程類型創建它們,並根據需要在實例上設置優先級。

3

它不聲稱低優先級 - 背景意味着a:不是UI線程,b:它不會保持進程活着。實際上,它可能與ThreadPool線程有關。

如果你想有一個特定的優先級的線程,然後使用自己的Thread對象 - 但我不會建議甚至這通常...

此外 - 「背景」並不意味着「空閒時」。即使在一臺核心機器上,你也可能會看到兩個線程獲得同樣多的rnutime(如果他們想要的話)。在多核上更是如此。

+0

問題是,當後臺線程調用UploadAsync,它似乎是阻止/減慢UI線程。我可以這樣說,因爲上傳發生時調試語句會暫停。我怎樣才能避免這種情況? – 2009-02-08 05:24:56

+0

你有多少核心?這項工作必須發生在某個地方...... – 2009-02-08 09:18:15

+0

這是一款雙核筆記本電腦,採用Win XP。 – 2009-02-08 18:25:27

7

是的,你的方法有問題 - 當隊列爲空時,你基本上是緊密循環的。無論線程優先級如何,這是一個糟糕的主意。

爲此使用後臺工作器沒什麼問題,但入隊/出隊應該只使用生產者/消費者隊列,當你沒有準備好任何東西時試圖出隊。

我有一個生產者/消費者隊列的示例實現in my threading tutorial - 查看鏈接頁面的大約一半。順便說一下,您需要某種方式來告訴離職過程它已完成。 (例如,將空引用或其他特殊值排入隊列。)該代碼被寫入預泛型,但應該易於更新。

+0

在您的示例中,您期望隊列中有10個項目,並且消費者線程在將10個項目出列時會終止。就我而言,項目會在整個應用程序生命週期中添加到隊列中(每秒大約10項),所以oWork不應該終止。那麼還有什麼可以做,但緊密的循環? – 2009-02-08 05:18:38