2012-09-03 113 views
0

我有以下的功能,最初被從UI(主)的線程調用:使用線程池適當

private void BreakToggle(int line, Boolean toggle) 
    { 
     string flag; 
     if (toggle) 
     { 
      flag = "0"; //Add 
     } 
     else 
     { 
      flag = "1"; //Delete 
     } 
     string logicLine = line.ToString(); 

     SetLogicBreakLineResponse response = ddcdao.SetLogicBreakLine(logicName, logicLine, flag); 
    } 

然而,底線試圖建立與電子裝置連接併發送一個信號,該信號如果連接速度慢,可能需要5秒鐘。所以爲了防止用戶界面掛起,我決定做一個單獨的線程來處理這個問題。

這個函數也可以在很短的時間內被調用很多次(比如1秒內的10次),所以我想通過使用Threadpool來代替背景工作,所以我修改了我的代碼像這樣:

ThreadPool.QueueUserWorkItem(state => 
{ 
     SetLogicBreakLineResponse response = ddcdao.SetLogicBreakLine(logicName, logicLine, flag); 
}); 

這是使用Threadpool的正確方法嗎?如果使用線程很簡單,我覺得我肯定做錯了什麼。此代碼是否會導致我的應用程序出現任何未知的伏都教?

+0

它看起來像是放棄了迴應。這是你的意圖嗎?如果多次撥打電話,訂單或對設備的呼叫很重要? – rene

回答

2

你的例子是使用線程池的合理開始。它可以像這樣簡單,如果你唯一感興趣的只是讓代碼在UI線程之外運行。

但是,你應該知道你的原始代碼和多線程版本之間的行爲差​​異:

  • 的MT版本不保證其順序排隊的操作將運行
  • 的MT版本允許一次運行多個操作的可能性,這意味着SetLogicBreakLine需要重入
  • 使用閉包捕獲引用類型的值可以讓它們的成員在安排它們之後並且在它們運行之前被突變

您確實需要考慮這些差異,但如果MT行爲沒有問題,那麼它就如此簡單。

+0

感謝您的詳細解答! – l46kok

+0

好點。另一個有趣的是,GUI的更新不應該從線程池線程完成,而是轉發到GUI線程。 – Tudor

1

我覺得我肯定是做錯了,如果使用線程是很容易的。

你沒有做錯任何事情,ThreadPool的整點是使線程的使用更加高效&容易。我要說的唯一的事情是,如果你需要在線程之外使用response,你可能需要重新考慮你的代碼。

+0

啊,我會在ThreadPool內部做一些響應。爲了說明的目的,我想盡量減少代碼。謝謝你的回答。 – l46kok