[.NET] 關於.NET線程問題總結(一)

來源:互聯網
上載者:User

基礎篇:

 

怎樣建立一個線程

我只簡單列舉幾種常用的方法,詳細可參考.Net多線程總結(一)

一)使用Thread類

ThreadStart threadStart=new ThreadStart(Calculate);//通過ThreadStart委託告訴子線程講執行什麼方法,這裡執行一個計算圓周長的方法
Thread thread=new Thread(threadStart);
thread.Start(); //啟動新線程

public void Calculate(){
double Diameter=0.5;
Console.Write("The perimeter Of Circle with a Diameter of {0} is {1}"Diameter,Diameter*Math.PI);
}
二)使用Delegate.BeginInvoke

delegate double CalculateMethod(double Diameter); //申明一個委託,表明需要在子線程上執行的方法的函數簽名
static CalculateMethod calcMethod = new CalculateMethod(Calculate);//把委託和具體的方法關聯起來
static void Main(string[] args)
{
//此處開始非同步執行,並且可以給出一個回呼函數(如果不需要執行什麼後續操作也可以不使用回調)
calcMethod.BeginInvoke(5, new AsyncCallback(TaskFinished), null);
Console.ReadLine();
}

//線程調用的函數,給出直徑作為參數,計算周長
public static double Calculate(double Diameter)
{
    return Diameter * Math.PI;
}

//線程完成之後回調的函數
public static void TaskFinished(IAsyncResult result)
{
    double re = 0;
    re = calcMethod.EndInvoke(result);
    Console.WriteLine(re);
}

三)使用ThreadPool.QueueworkItem

WaitCallback w = new WaitCallback(Calculate);
//下面啟動四個線程,計算四個直徑下的圓周長
ThreadPool.QueueUserWorkItem(w, 1.0);
ThreadPool.QueueUserWorkItem(w, 2.0);
ThreadPool.QueueUserWorkItem(w, 3.0);
ThreadPool.QueueUserWorkItem(w, 4.0);
public static void Calculate(double Diameter)
{
return Diameter * Math.PI;
}

 

 

線程相關解釋:

 

一)受託管的線程與 Windows線程
必須要瞭解,執行.NET應用的線程實際上仍然是Windows線程。但是,當某個線程被CLR所知時,我們將它稱為受託管的線程。具體來說,由受託管的代碼建立出來的線程就是受託管的線程。如果一個線程由非託管的代碼所建立,那麼它就是非託管的線程。不過,一旦該線程執行了受託管的代碼它就變成了受託管的線程。

一個受託管的線程和非託管的線程的區別在於,CLR將建立一個System.Threading.Thread類的執行個體來代表並操作前者。在內部實現中,CLR將一個包含了所有受託管線程的列表儲存在一個叫做ThreadStore地方。

CLR確保每一個受託管的線程在任意時刻都在一個AppDomain中執行,但是這並不代表一個線程將永遠處在一個AppDomain中,它可以隨著時間的推移轉到其他的AppDomain中。

從安全的角度來看,一個受託管的線程的主使用者與底層的非託管線程中的Windows主使用者是無關的。

二)前台線程與後台線程

啟動了多個線程的程式在關閉的時候卻出現了問題,如果程式退出的時候不關閉線程,那麼線程就會一直的存在,但是大多啟動的線程都是局部變數,不能一一的關閉,如果調用Thread.CurrentThread.Abort()方法關閉主線程的話,就會出現ThreadAbortException 異常,因此這樣不行。
後來找到了這個辦法: Thread.IsBackground 設定線程為後台線程。

msdn對前台線程和後台線程的解釋:託管線程或者是後台線程,或者是前台線程。後台線程不會使託管執行環境處於活動狀態,除此之外,後台線程與前台線程是一樣的。一旦所有前台線程在主控處理序(其中 .exe 檔是託管程式集)中被停止,系統將停止所有後台線程並關閉。通過設定 Thread.IsBackground 屬性,可以將一個線程指定為後台線程或前台線程。例如,通過將 Thread.IsBackground 設定為 true,就可以將線程指定為後台線程。同樣,通過將 IsBackground 設定為 false,就可以將線程指定為前台線程。從Unmanaged 程式碼進入託管執行環境的所有線程都被標記為後台線程。通過建立並啟動新的 Thread 對象而產生的所有線程都是前台線程。如果要建立希望用來偵聽某些活動(如通訊端串連)的前台線程,則應將 Thread.IsBackground 設定為 true,以便進程可以終止。
所以解決辦法就是在主線程初始化的時候,設定:Thread.CurrentThread.IsBackground = true;

這樣,主線程就是後台線程,在關閉主程式的時候就會關閉主線程,從而關閉所有線程。但是這樣的話,就會強制關閉所有正在執行的線程,所以在關閉的時候要對線程工作的結果儲存。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.