在上一遍文章中講到多執行緒基礎,在此篇文章中我們來學習C#裡面Thread類。Thread類是在.net framework1.0版本中推出的API。如果對執行緒的概念還不太清楚的小夥伴請閱讀我的上一遍文章:多執行緒系列(一),多執行緒基礎
在本篇文章中新開啟一個執行緒來非同步呼叫的方法程式碼為:
private void DoSomeThing(string btnName) { Console.WriteLine($"{btnName} 開始,當前執行緒id:{Thread.CurrentThread.ManagedThreadId}"); long lResult = 0; for (long i = 0; i < 1_00_000_000; i++) { lResult += i; } Console.WriteLine($"{btnName} 結束,當前執行緒id:{Thread.CurrentThread.ManagedThreadId}"); }
如何使用Thread來開啟一個新的執行緒?
方式一:基於委託ParameterizedThreadStart
ParameterizedThreadStart method = o => this.DoSomeThing("btnThread_Click"); Thread thread = new Thread(method); thread.Start();//開啟執行緒,執行委託的內容
方式二:基於委託ThreadStart
ThreadStart method = () => { Thread.Sleep(3000); this.DoSomeThing("btnThread_Click"); }; Thread thread = new Thread(method); thread.Start();//開啟執行緒,執行委託的內容
執行緒的暫停(掛起)、休眠、繼續、終止
thread.Suspend();//暫停,掛起執行緒,如果執行緒已經掛起,則不起作用
thread.Resume();//繼續已經掛起的執行緒
thread.Abort();//終止執行緒,會在當前執行緒中丟擲一個異常引發執行緒停止,不過會有延遲,因為執行緒屬於計算機資源,程式想停下執行緒,只能向作業系統通知(拋異常),不一定真的能停下來
Thread.ResetAbort();//終止當前執行緒,取消當前執行緒的所有請求,只能終止一次
Thread.Sleep();//使當前執行緒休眠多少毫秒再繼續執行
執行緒等待
方式一:通過thread.ThreadState獲取當前執行緒的狀態
while (thread.ThreadState != System.Threading.ThreadState.Stopped) { Thread.Sleep(500); Console.WriteLine($"執行緒_{ thread.ManagedThreadId.ToString("00")}_正在執行中..."); }
方式二:通過Join等待
thread.Join(); //等待執行緒thread執行完畢
thread.Join(5000); //限時等待,最多等待5000毫秒
執行緒的優先順序
thread.Priority = ThreadPriority.Highest;
設定執行緒的優先順序為最高優先順序:優先執行,但不代表優先完成,甚至說極端情況下,還有意外發生,不能通過這個來控制執行緒的執行先後順序
前臺執行緒與後臺執行緒
thread.IsBackground = false;//預設是false 前臺執行緒,程式關閉,執行緒需要計算完後才退出
thread.IsBackground = true; //關閉程式,執行緒退出
執行緒的回撥
我們希望某個執行緒在執行某個動作之後觸發另一個動作,下面是我基於Thread封裝的執行緒回撥函式
/// <summary> /// 基於thread封裝一個回撥,啟動子執行緒執行動作A--不阻塞--A執行完後子執行緒會執行動作B,不阻塞 /// </summary> /// <param name="method">動作A</param> /// <param name="action">動作B</param> private void ThreadWithCallBack(ThreadStart method,Action action) { ThreadStart threadStart = () => { method.Invoke(); action.Invoke(); }; new Thread(threadStart).Start(); }
呼叫測試程式碼:
ThreadStart method = () => { this.DoSomeThing("btnThread_Click"); }; Action actionCallBack = () => { Console.WriteLine("method 的回撥"); }; this.ThreadWithCallBack(method, actionCallBack);
獲取子執行緒的返回值
下面是我基於Thread封裝的獲取子執行緒的返回值函式
T t = default(T); ThreadStart threadStart = () => { t = func.Invoke(); }; Thread thread = new Thread(threadStart); thread.Start(); return new Func<T>(() => { thread.Join(); return t; });
呼叫測試程式碼
Func<int> func = () => { return DateTime.Now.Hour; }; Func<int> funcThread = this.ThreadWithReturn<int>(func);//非阻塞 int res = funcThread.Invoke();//阻塞
在下一篇中,會繼續講到執行緒池