這篇文章主要給出 ThreadThreadPool 的使用示例

Thread的使用

默認情況下

  • 應用程序主線程為前臺線程
  • 通過 Thread 構造函數創建的線程為前臺線程

using System.Threading;

public class App {
public static void Main() {
// 以一個方法為參數,傳遞給 Thread
// 該參數會隱式的轉換為 public delegate void ThreadStart() 委託
Thread thread = new Thread(DoWork);
thread.Start();

// 調用此方法的意思是:等待 thread 執行完畢,之後再執行此後的語句
thread.Join();

Thread threadWithArgs = new Thread(DoOtherWork);
/// 此處將線程 threadWithArgs 聲明為後臺線程
/// 後臺線程與前臺線程的區別在於:如果所有前臺線程結束了,後臺線程無法阻止進程退出,因為這時,所有的後臺線程都會被強行關閉
/// 如果不聲明,則默認為前臺線程
threadWithArgs.IsBackground = true;
threadWithArgs.Start("Thread with arguments");
}

/// <summary>
/// 當線程被啟用(調用Thread.Start)之後,會執行此方法
/// </summary>
private static void DoWork() {
// 業務邏輯代碼
}

/// <summary>
/// 當線程被啟用(調用Thread.Start)之後,會執行此方法
/// </summary>
private static void DoOtherWork(object args) {
// args 是啟動線程時傳遞的參數

// 業務邏輯
}
}

ThreadPool的使用

線程池裡面的線程,默認以後臺線程的方式運行,優先順序為ThreadPriority.Normal。它通過有限的幾個線程為大量的操作服務,減少了創建和銷毀線程所需的時間,從而提高效率

以下幾種情況,默認使用線程池

  • 通過 Task 或者 Task 來執行某些任務時
  • System.Threading.Timer 執行回調函數時;從 System.Timers.Timer 觸發事件時
  • 當註冊了等待句柄,在等待句柄完成之後,執行具體任務時
  • 通過 ThreadPool.QueueUserWorkItem 方式使用線程時

在以下情況,不應該使用線程池

  • 線程需要執行很長的時間
  • 需要為線程指定優先順序的時候
  • 在執行過程中,需要睡眠、掛起線程時

因此,線程池適合併發運行一些耗時較短的任務。在 .NET 4.0 之後,推薦使用 Task 或者 Task<T>,它們不但使用更方便,並且效率及可控性都比 ThreadThreadPool 要好

ThreadPool用法如下

using System;
using System.Threading;

public class App {
public static void Main() {
// 將工作任務指派給線程池
ThreadPool.QueueUserWorkItem(DoWork);

// 將工作任務指派給線程池
ThreadPool.QueueUserWorkItem(DoWorkWithArgs, "This is Work item");
Thread.Sleep(1000);

Console.ReadLine();
}

/// <summary>
/// 當工作任務被指派給線程池(調用ThreadPool.QueueUserWorkItem)之後,會執行此方法
/// </summary>
static void DoWork(object noArgs) {
// 無狀態數據時
Console.WriteLine("DoWork. no state work item.");
}

/// <summary>
/// 當工作任務被指派給線程池(調用ThreadPool.QueueUserWorkItem)之後,會執行此方法
/// </summary>
static void DoWorkWithArgs(object stateInfo) {
// 有狀態數據時
Console.WriteLine($"DoWorkWithArgs. The state data is {stateInfo as string}.");
}
}

輸出如下

DoWork. no state work item.
DoWorkWithArgs.The state data is This is Work item.

值得提醒的是,ThreadPool.QueueUserWorkItem 的回調函數,都必須有一個 object 類型的參數,否則,會出現編譯錯誤

這是由 WaitCallback 這個委託決定的,其定義如下

public delegate void WaitCallback(object state);

至此,本節內容講解完畢。

歡迎關注公眾號【嘿嘿的學習日記】,所有的文章,都會在公眾號首發,Thank you~

推薦閱讀:

相關文章