.net多線程探索(multiThreading)

2005-09-09

初探.NET多線程

         好多天沒有更新Blog了,一直都在忙着尋找如何將IronPython集成至GUI中的方法。一開始我把問題看得太簡單了,因爲我看了來自CodeProject的ShellControl - A console emulation control這篇文章之後,很幼稚地認爲只需要把源代碼中的cmd.exe換IronPythonConsole.exe 就可以大功告成了,然而事實證明我的想法是很愚蠢的。儘管IronPythonConsole與cmd同爲可執行文件,但是它們與作爲輸入輸出的RichTextBox之間的關係是不同的。對cmd而言,是一種順序的處理方式:TextBox接受用戶輸入-> 用戶按下Enter觸發相應的EventHandler,在EventHandler中創建Process以運行cmd.exe -> 將結果返回至TextBox。在這個過程中,每一條指令的輸入都會相應地創建新的Process,而這個Process的life cycle僅僅存在於用戶按下Enter觸發的事件響應函數中;反觀IronPythonConsole的情況就不是這樣的了,我們需要的是一個GUI Thread來響應用戶的輸入,同時需要一個Worker Thread調用IronPythonConsole來完成用戶輸入並給出相應的輸出,很明顯我需要進行多線程的開發了。面對着多線程,我真的很困窘,因爲自己在這個方面的經驗幾乎爲零。不過沒有辦法,爲了FantasyPython,只能明知山有虎,偏向虎山行了。
        也許是自己天性愚鈍吧,看了兩天的文章,也還沒有很好的solution,不過對於Multithreading倒是有了一點小小的認識,謹記於此。首先是使用多線程的重要性了。這點其實不必多言,大家都會知道把佔用大量CPU週期的數據處理放到GUI Thread中,造成GUI無法響應用戶的操作是一種十分糟糕的做法。爲了實現更好的用戶體驗,就應該創建新的進程來處理持續時間較長的操作,通常我們會把負責非UI操作的進程稱爲Worker Thread(工作進程)。重要性說完了,讓我們關注到更具體的多線程實現上來。
        在.NET中進行多線程開發,會有很多選擇,其中最常見的就是使用Control.Invoke方法了。Invoke方法提供了一種在Worker Thread調用GUI Thread中delegate的途徑。同時結合Control.InvokeRequired的屬性,我們也可以輕易地判斷某個線程是否爲創建該Control的線程。爲了對Invoke方法有更深入的認識,我仔細地閱讀了CodeProject上《Worker Threads In C#》一文[1]。在文中有這樣的代碼:
m_form.Invoke(m_form.m_DelegateAddString, new Object[] {s});

這裏給出了Invoke方法的一種使用方式,但是可惜的是,我並不能對其使用的必要性有充分的理解。因爲我把這段代碼改爲m_form.AddString(s),並且將AddString方法的access modifier由private改爲public,程序仍然是運行好好的。那麼Invoke方法的意義在於什麼呢?而MSDN給Invoke方法下的定義又是如此的簡單:Executes the specified delegate on the thread that owns the control's underlying window handle. 真的是看不明白了,煩請各位朋友不吝賜教。
        問題雖然有,但是認識還得接着說。多線程開發很重要的一點就是線程間的通信問題,在CodeProject的這篇文章中,Worker Thread與GUI Thread是通過ManualResetEvent來實現的。我們從文中的代碼:
// Worker Thread
if ( m_EventStop.WaitOne(0true) ) {
    m_EventStopped.Set();
    
return
;
}


// GUI Thread
if ( m_WorkerThread != null  &&  m_WorkerThread.IsAlive ) {
    m_EventStopThread.Set();
    
while (m_WorkerThread.IsAlive) 
{
        
if ( WaitHandle.WaitAll((new ManualResetEvent[] {m_EventThreadStopped}), 100,true) ) 
{
            
break
;
        }


        Application.DoEvents();
    }

}

  
可以看到Worker Thread與GUI Thread之間的通信過程:
        1、當Worker Thread處於活動狀態,而GUI Thread通過設置m_EventStopThread的狀態向Worker Thread發出Signal,並使自己進入循環等待狀態,直至接收到由Worker Thread發出的Signal;
        2、Worker Thread在接收到該Signal之後採取相應的操作,例子中的操作就是通過設置m_EventStopped的狀態向GUI Thread發出自己已經停止的Signal並且返回;
        3、GUI Thread接收到來自Worker Thread發出的Signal後,跳出循環;
        呼,終於說完了。由於自己剛剛開始接觸C#的MultiThreading開發,疏漏一定不少。請各位路過的朋友不要錯過扔磚頭的機會哦,^_^

        [1]
小新0574爲這篇不錯的文章提供了譯文,有興趣的朋友可以參考一下中文版。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章