C# 實現執行緒的常用幾種方式
阿新 • • 發佈:2021-06-25
前言
在各個開發語言中,執行緒是避免不了的,或許通過表象看不出來,但是真的無處不在。就比如一個Web程式,平時或許只注重增刪改查的開發,根本沒有編寫相關多執行緒的的程式碼,但是請求內部的時候,已經分配了對應執行緒進行處理了,以下簡單說說C#中使用執行緒的幾種方式,詳細使用後續繼續記錄。
Thread類實現
Thread類的實現方式,在C# .NetFramework剛出的時候就已經存在了,起初剛開始的程式設計師都使用這種方式,但經歷後面幾個.NetFramework的版本更新,實現方式變的更多了。
public void TestThread()
{
//這裡需要注意的是:在C#中執行緒是離不開委託的
//建立了一個執行緒物件,這裡建構函式提供兩類,一種不帶引數的,一種是帶引數的
Thread thread = new Thread( TestAction);
//設定執行緒相關屬性
thread.IsBackground = true;
thread.Name = "Test";
//啟動執行緒
thread.Start();
}
/// <summary>
/// 執行緒執行的方法
/// </summary>
private void TestAction()
{
//這裡實現執行緒處理的相關業務
Console.WriteLine($"子執行緒Thread({Thread.CurrentThread.Name})執行相關業務操作....{Thread.CurrentThread.ManagedThreadId}");
}
執行結果:
ThreadPool 執行緒池實現
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace MutltiThreadImplement
{
/// <summary>
/// ThreadPool 池化執行緒,避免頻繁的申請和釋放消耗資源;之前Thread每次都要申請和釋放。
/// </summary>
public class ThreadPoolImplement
{
public void TestThreadPool()
{
//可以設定相關屬性
ThreadPool.SetMinThreads(5,10);
ThreadPool.SetMaxThreads(6, 10);
//通過執行緒池自動分配執行緒執行對應的業務功能
ThreadPool.QueueUserWorkItem(TestAction);
}
private void TestAction( object state)
{
//這裡實現執行緒處理的相關業務
Console.WriteLine($ "子執行緒Thread({Thread.CurrentThread.Name})執行相關業務操作....{Thread.CurrentThread.ManagedThreadId}" );
}
}
}
|
執行結果:
ThreadPool的使用是不是感覺比較簡單,但是就是因為太簡單了,在業務中有些需求得不到滿足,比如試著控制執行緒順序;
Delegate 實現的多執行緒
public void TestDelegateThread()
{
//定義一個強型別委託, 可以自定義委託
Action action = TestAction;
//開始非同步操作,其實內部是開啟了子執行緒,看執行緒id不一樣就明白了
IAsyncResult asyncResult = action.BeginInvoke(CallBack, null);
//可以根據返回物件的一些屬性和方法進行判斷和業務邏輯執行 具體可以檢視相關文件
//asyncResult.IsCompleted; //判讀是否執行完成
//asyncResult.AsyncWaitHandle.WaitOne(); //阻塞當前執行緒,直到收到訊號量
}
private void TestAction()
{
//這裡實現執行緒處理的相關業務
Console.WriteLine($"子執行緒Thread({Thread.CurrentThread.Name})執行相關業務操作....{Thread.CurrentThread.ManagedThreadId}");
}
/// <summary>
/// 子執行緒執行完成時的回撥
/// </summary>
private void CallBack(IAsyncResult ar)
{
Console.WriteLine($"子執行緒{Thread.CurrentThread.ManagedThreadId}執行完畢");
}
執行結果:
注: 這種方式在.NetCore環境不支援,提示平臺不支援。
BackGroundWorker 實現
BackgroundWorker backgroundWorker = new BackgroundWorker();
public void TestBackGroundWorker()
{
//這裡使用的是事件的方式繫結業務處理方法
backgroundWorker.DoWork += TestAction;
//可以繫結一些事件 使用很簡單,可以不需要繫結以下事件和設定屬性就可以執行,根據需要進行繫結
//執行完成事件
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
backgroundWorker.ProgressChanged += BackgroundWorker_ProgressChanged;
backgroundWorker.WorkerReportsProgress = true;//只有執行這個屬性之後才能進行ProgressChanged觸發
//開始執行操作
backgroundWorker.RunWorkerAsync();
}
/// <summary>
/// 觸發事件之後的業務處理
/// </summary>
private void BackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("可以在這裡更新UI執行緒上的東西....");
}
/// <summary>
/// 觸發事件之後的業務處理
/// </summary>
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
Console.WriteLine($"子執行緒{Thread.CurrentThread.ManagedThreadId}執行完成!!!");
}
private void TestAction(object sender, DoWorkEventArgs e)
{
//這裡實現執行緒處理的相關業務
Console.WriteLine($"子執行緒Thread({Thread.CurrentThread.Name})執行相關業務操作....{Thread.CurrentThread.ManagedThreadId}");
//在業務方法中執行ReportProgress方法會觸發ProgressChanged事件
backgroundWorker.ReportProgress(10);
Console.WriteLine($"子執行緒Thread({ Thread.CurrentThread.ManagedThreadId})執行相關業務操作結束");
}
執行結果:
BackgroundWorker 這種方式比較適應於窗體應用程式。
Task 實現多執行緒
/// <summary>
/// Task 實現多執行緒, 目前為止,Task方式是大家都比較推薦的方式
/// </summary>
public void TestTask()
{
//建立一個Task例項
Task task = new Task(TestAction);
//開始任務
task.Start();
}
private void TestAction()
{
//這裡實現執行緒處理的相關業務
Console.WriteLine($"子執行緒Thread({Thread.CurrentThread.Name})執行相關業務操作....{Thread.CurrentThread.ManagedThreadId}");
}
執行結果
Task實現多執行緒的方式是大家一致推薦的,俗稱最佳實踐。
Parallel實現多執行緒
/// <summary>
/// Parallel 是對Task的進一步封裝,但會阻塞主執行緒,主執行緒會參與業務邏輯處理
/// </summary>
public class ParallelImplement
{
public void TestParallel()
{
//分配執行緒執行業務邏輯, Invoke可傳多個業務處理,內部會自動分配執行緒處理
Parallel.Invoke(TestAction);
}
private void TestAction()
{
//這裡實現執行緒處理的相關業務
Console.WriteLine($"子執行緒Thread({Thread.CurrentThread.Name})執行相關業務操作....{Thread.CurrentThread.ManagedThreadId}");
}
}
執行結果:
根據執行結果得出結論,主執行緒參與業務邏輯處理中,會阻塞執行緒, Parallel可根據業務進行選擇使用。
總結
以上基本上就是C#中使用多執行緒常用的幾種方式,這裡只是簡單的彙總方式,沒有深入分析,後續將針對模組進行分析。