天天看點

C#基礎系列——多線程的常見用法詳解

前言:前面幾節分别介紹了下C#基礎技術中的反射、特性、泛型、序列化、擴充方法、Linq to Xml等,這篇跟着來介紹下C#的另一基礎技術的使用。最近項目有點緊張,是以準備也不是特别充分。此篇就主要從部落客使用過的幾種多線程的用法從應用層面大概介紹下。文中觀點都是部落客個人的了解,如果有不對的地方望大家指正~~

1、多線程:使用多個處理句柄同時對多個任務進行控制處理的一種技術。據部落客的了解,多線程就是該應用的主線程任命其他多個線程去協助它完成需要的功能,并且主線程和協助線程是完全獨立進行的。不知道這樣說好不好了解,後面慢慢在使用中會有更加詳細的講解。

2、多線程的使用:

(1)最簡單、最原始的使用方法:Thread oGetArgThread = new Thread(new ThreadStart(() =>{});這種用法應該大多數人都使用過,參數為一個ThreadStart類型的委托。将ThreadStart轉到定義可知:

它是一個沒有參數,沒有傳回值的委托。是以他的使用如下:

    for (var i = 0; i < 1000000; i++)

    {

      Console.WriteLine("主線程計數" + i);

      //Thread.Sleep(100);

    }

定義一個沒有參數沒有傳回值的方法傳入該委托。當然也可以不定義方法寫成匿名方法:

這個和上面的意義相同。得到的結果如下:

C#基礎系列——多線程的常見用法詳解

說明主線程和背景線程是互相獨立的。由系統排程資源去執行。

如果這樣那有人就要問了,如果我需要多線程執行的方法有參數或者有傳回值或者既有參數又有傳回值呢。。。别着急我們來看看new Thread()的幾個構造函數:

轉到定義可知參數有兩類,一類是無參無傳回值的委托,另一類是有參無傳回值的委托。對于有參數的委托使用方法:

對于有參又有傳回值的委托,很顯然使用new Thread()這種方式是沒有解決方案的。其實對于有參又有傳回值的委托可以使用異步來實作:

關于這種方式還有幾點值得一說的是:

①Thread oGetArgThread = new Thread(new ThreadStart(Test));

oGetArgThread.Join();//主線程阻塞,等待分支線程運作結束,這一步看功能需求進行選擇,主要為了多個程序達到同步的效果

②線程的優先級可以通過Thread對象的Priority屬性來設定,Priority屬性對應一個枚舉:

從0到4,優先級由低到高。

③關于多個線程同時使用一個對象或資源的情況,也就是線程的資源共享,為了避免資料紊亂,一般采用.Net悲觀鎖lock的方式處理。

(2)Task方式使用多線程:這種方式一般用在需要循環處理某項業務并且需要得到處理後的結果。使用代碼如下:

使用這種方式的時候需要注意這一句 var bdTmp = bd;這裡必須要用一個臨時變量,要不然多個bd對象容易串資料。如果有興趣可以調試看看。這種方法比較簡單,就不多說了。當然Task對象的用法肯定遠不止如此,還涉及到任務的排程等複雜的邏輯。部落客對這些東西了解有限,就不講解了。

(3)線程池的用法:一般由于考慮到伺服器的性能等問題,保證一個時間段内系統線程數量在一定的範圍,需要使用線程池的概念。大概用法如下:

需要注意:Semaphore對象的數量需要根據伺服器的性能來設定;System.Threading.Tasks.Parallel.ForEach這種方式表示同時啟動lstTestBed.Length個線程去做一件事情,可以了解為

(4) 多線程裡面還有一個值得一說的SpinWait類,用于提供對基于自旋的等待的支援。也就是說支援重複執行一個委托,知道滿足條件就傳回,我們來看它的用法:

這個方法有三個構造函數,後兩個需要傳入一個時間,表示如果再規定的時間内還沒有傳回則自動跳出,防止死循環。

部落客使用過的多線程用法大概就這麼三大類,當然這些其中還涉及很多細節性的東西,部落客原來使用這些的時候經常出現各種莫名的問題,可能還是沒用好的原因,對這些東西了解還不夠深刻。如果大家也遇到類似的問題可以拿出來探讨!!

多線程用法示例

繼續閱讀