天天看點

細說多線程(三)—— 以ThreadStart方式實作多線程

目錄

<a href="http://blog.51cto.com/2689556/835785" target="_blank">一、線程的定義</a>

<a target="_blank" href="http://blog.51cto.com/2689556/835794">二、線程的基礎知識</a>

<a href="http://blog.51cto.com/2689556/835815" target="_blank">三、以ThreadStart方式實作多線程</a>

<a href="http://blog.51cto.com/2689556/835832" target="_blank">四、CLR線程池的工作者線程</a>

<a href="http://blog.51cto.com/2689556/835851" target="_blank">五、CLR線程池的I/O線程</a>

<a href="http://blog.51cto.com/2689556/835861" target="_blank">六、異步 SqlCommand</a>

<a href="http://blog.51cto.com/2689556/835866" target="_blank">七、并行程式設計與PLINQ</a>

<a target="_blank" href="http://79100812.blog.51cto.com/2689556/835881">八、計時器與鎖</a>

三、以ThreadStart方式實作多線程

3.1 使用ThreadStart委托

這 裡先以一個例子展現一下多線程帶來的好處,首先在Message類中建立一個方法ShowMessage(),裡面顯示了目前運作線程的Id,并使用 Thread.Sleep(int ) 方法模拟部分工作。在main()中通過ThreadStart委托綁定Message對象的ShowMessage()方法,然後通過 Thread.Start()執行異步方法。

請注意運作結果,在調用Thread.Start()方法後,系統以異步方式運作Message.ShowMessage(),而主線程的操作是繼續執行的,在Message.ShowMessage()完成前,主線程已完成所有的操作。

<a target="_blank" href="http://blog.51cto.com/attachment/201204/151514804.jpg"></a>

3.2 使用ParameterizedThreadStart委托

ParameterizedThreadStart 委托與ThreadStart委托非常相似,但ParameterizedThreadStart委托是面向帶參數方法的。注意 ParameterizedThreadStart 對應方法的參數為object,此參數可以為一個值對象,也可以為一個自定義對象。

運作結果:

<a target="_blank" href="http://blog.51cto.com/attachment/201204/151552365.jpg"></a>

3.3 前台線程與背景線程

注意以上兩個例子都沒有使用Console.ReadKey(),但系統依然會等待異步線程完成後才會結束。這是因為使用Thread.Start()啟動的線程預設為前台線程,而系統必須等待所有前台線程運作結束後,應用程式域才會自動解除安裝。

在第二節曾經介紹過線程Thread有一個屬性IsBackground,通過把此屬性設定為true,就可以把線程設定為背景線程!這時應用程式域将在主線程完成時就被解除安裝,而不會等待異步線程的運作。

3.4 挂起線程

為了等待其他背景線程完成後再結束主線程,就可以使用Thread.Sleep()方法。

運作結果如下,此時應用程式域将在主線程運作5秒後自動結束

<a target="_blank" href="http://blog.51cto.com/attachment/201204/151635879.jpg"></a>

但 系統無法預知異步線程需要運作的時間,是以用通過Thread.Sleep(int)阻塞主線程并不是一個好的解決方法。有見及此,.NET專門為等待異 步線程完成開發了另一個方法thread.Join()。把上面例子中的最後一行Thread.Sleep(5000)修改為 thread.Join() 就能保證主線程在異步線程thread運作結束後才會終止。

3.5 Suspend 與 Resume (慎用)

Thread.Suspend() 與 Thread.Resume()是在Framework1.0 就已經存在的老方法了,它們分别可以挂起、恢複線程。但在Framework2.0中就已經明确排斥這兩個方法。這是因為一旦某個線程占用了已有的資源, 再使用Suspend()使線程長期處于挂起狀态,當在其他線程調用這些資源的時候就會引起死鎖!是以在沒有必要的情況下應該避免使用這兩個方法。

3.6 終止線程

若想終止正在運作的線程,可以使用Abort()方法。在使用Abort()的時候,将引發一個特殊異常 ThreadAbortException 。

若想線上程終止前恢複線程的執行,可以在捕獲異常後 ,在catch(ThreadAbortException ex){...} 中調用Thread.ResetAbort()取消終止。

而使用Thread.Join()可以保證應用程式域等待異步線程結束後才終止運作。

運作結果如下

<a href="http://blog.51cto.com/attachment/201204/151722737.jpg" target="_blank"></a>

本文轉自 leslies2  51CTO部落格,原文連結:http://blog.51cto.com/79100812/835815