玩轉C#之【執行序-實際實作】

更新 發佈閱讀 13 分鐘

介紹

raw-image

定義

處理序(Process) (大陸:進程): 一個程序運行時,占用全部計算資源的總和

執行緒(Thread) (大陸:線程):是作業系統能夠進行運算排程的最小單位。 大部分情況下,它被包含在行程之中,是行程中的實際運作單位。

C#多線程和異步(一)——基本概念和使用方法

執行緒帶來的負擔

Windows 每建立一條執行緒,須為它配置大約 1MB 左右的記憶體,其中包含執行緒核心物件、環境區塊(Thread Environment Block)、使用者模式堆疊、核心模式堆疊等等。這是記憶體空間的額外負擔。

Thread

C# 1.0 1.1 的多執行緒方法

方法:查詢目前執行緒的ID

Thread.CurrentThread.ManagedThreadId

演示用的函示

private void doSomething(string name)
{
Console.WriteLine($"doSomething {name}Start 執行緒:{Thread.CurrentThread.ManagedThreadId}");
long lRestul = 0;
for (int i = 0; i < 1000000; i++)
{
lRestul++;
}
Thread.Sleep(2000);
Console.WriteLine($"doSomething {name}End 執行緒:{Thread.CurrentThread.ManagedThreadId}");
}

建立執行緒、並啟動執行

我們可以從Thread建構式中看出他需要一個ThreadStart型別的參數

public Thread(ThreadStart start);

可以再看出ThreadStart 是一個委派的型別

public delegate void ThreadStart();

// Action action = () => this.doSomething("button3");
ThreadStart threadStart = () => this.doSomething("button3");//委派
//Thread thread =new Thread(action);
Thread thread = new Thread(threadStart);
thread.Start();//啟動

執行緒暫停、喚醒、銷毀

舊方法不建議使用

thread.Suspend();//執行緒暫停  舊方法-被遺棄了-不建議使用-容易造成死鎖
thread.Resume();//執行緒喚醒 舊方法-被遺棄了-不建議使用

不建議使用,它是利用拋出例外的方式,所以需要用try catch包住

try
{
thread.Abort();//銷毀,方式是拋棄異常 也不建議 不一定及時
}
catch (Exception)
{
Thread.ResetAbort();//取消異常
}

執行緒等待

可以使用以下兩種方式,解決執行緒等待

ThreadState狀態介紹
1.主執行緒判斷子執行緒的狀態是否為停止,如果還沒停止就讓主執行緒sleep

while (thread.ThreadState != ThreadState.Stopped)
{
Thread.Sleep(100);//當前執行緒 休息100ms
}

2.使用Join,當前執行緒等待thread完成

//執行緒等待
thread.Join(500);//最多等待500
Console.WriteLine("最多等待500ms");
thread.Join();//當前執行緒等待thread完成

Thread的特點IsBackground

所有的執行緒都是默認前台,就是當子執行緒任務完成之後,程式才可以退出
只有Thread可以設定子執行緒是前台或後台

//IsBackground 是Thread的特點 只有thread可以設定前台,後台
Console.WriteLine(thread.IsBackground);
//默認是前台線程,啟動後一定要先完成任務的,阻止進程退出
thread.IsBackground = true;//指定後台線程 隨者程式退出

設定執行緒優先級別

沒什麼作用

thread.Priority = ThreadPriority.Highest;//設定線程優先級別
//CPU會依優先執行Highest 不代表Highest 就最先結束

結論:

thread已經越來越少人在使用了 不是主流

ThreadPool-執行緒集區(大陸:線程池)

2.0 線程池 - 實作方式:享元模式 --數據庫連接池
1.thread提共太多的API,給三歲小孩一把槍
2.無限使用線程,ThreadPool加以限制
3.重用線程,避免重複的創建與銷毀

享元模式

執行方式

ThreadPool.QueueUserWorkItem(t => this.doSomething("button4_Click"));

取得環境中最大可以使用的執行緒數量

public static void GetMaxThreads (out int workerThreads, out int completionPortThreads);

參數
workerThreads
Int32
執行緒集區中的背景工作執行緒最大數目。
completionPortThreads
Int32
執行緒集區中的非同步 I/O 執行緒最大數目。

ThreadPool.GetAvailableThreads(out int workerThreads, 
out int portThreads);

設定線程池最大數量跟最小數量

ThreadPool.SetMaxThreads(16, 16);
ThreadPool.SetMinThreads(8, 8);

執行緒等待

ThreadPool啥都沒有 所以要做等待可以使用以下方式

ManualResetEvent

ManualResetEvent 包含了一個bool屬性
false -- waitOne等待-- set true --WaitOne 才會往下執行
true --WaitOne會直接往下執行 --reset --false WaitOne 等待

ManualResetEvent manualResetEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(t =>
{
this.doSomething("btnThreadPool");
manualResetEvent.Set();
//manualResetEvent.Reset();
});
manualResetEvent.WaitOne();

Console.WriteLine("等待QueueUserWorkItem完成後才執行");

一般來說,不要阻礙執行緒的執行,很容易不小心造成死鎖

Thread Callback範例

無返回值的非同步Callback

var fun = this.ThreadWidthReturn<int>(() =>
{
Console.WriteLine($"fun 執行緒:{Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(2000);
return DateTime.Now.Millisecond;
});
Console.WriteLine("123");

int iResult = fun.Invoke();
Console.WriteLine($"{iResult}");
private void ThreadWithCallback(Action act, Action callback)
{
Thread thread = new Thread(() =>
{
act.Invoke();
callback.Invoke();
});
thread.Start();
}

有返回值的非同步Callback

要結果,不阻塞

var fun = this.ThreadPoolWidthReturn<int>(() =>
{
Console.WriteLine($"fun 執行緒:{Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(2000);
return DateTime.Now.Millisecond;
});
Console.WriteLine("123");

int iResult = fun.Invoke();
Console.WriteLine($"{iResult}");
private Func<T> ThreadWidthReturn<T>(Func<T> func)
{
T t = default(T);
Thread thread = new Thread(() =>
{
t = func.Invoke();
});
Console.WriteLine($"ThreadWidthReturn 執行緒:{Thread.CurrentThread.ManagedThreadId}");
thread.Start();

return () =>
{
thread.Join();
Console.WriteLine($"return 執行緒:{Thread.CurrentThread.ManagedThreadId}");
return t;
};
}

參考資料

C# 開發實戰:非同步程式開發技巧

本篇已同步發表至個人部落格
https://moushih.com/2022ithome19/

我的鐵人賽文章列表

https://ithelp.ithome.com.tw/articles/10292658

留言
avatar-img
一代軍師
8會員
39內容數
我是這個部落格的作者,喜歡分享有關投資 💰、軟體開發 💻、占卜 🔮 和虛擬貨幣 🚀 的知識和經驗。
一代軍師的其他內容
2024/02/12
盤面基本組成要素 十天干:甲乙丙丁戊己庚辛壬癸 十二地支:子丑寅卯辰巳午未申酉戌亥 五行:木、火、土、金、水 八門:休、生、傷、杜、景、死、驚、開 八神:符、蛇、陰、合、虎、武、九、天 九星:蓬、任、沖、輔、英、芮、柱、心、禽 八卦:坎、艮、震、兌、離、坤、乾 六個旬首:甲子戊、甲戊
Thumbnail
2024/02/12
盤面基本組成要素 十天干:甲乙丙丁戊己庚辛壬癸 十二地支:子丑寅卯辰巳午未申酉戌亥 五行:木、火、土、金、水 八門:休、生、傷、杜、景、死、驚、開 八神:符、蛇、陰、合、虎、武、九、天 九星:蓬、任、沖、輔、英、芮、柱、心、禽 八卦:坎、艮、震、兌、離、坤、乾 六個旬首:甲子戊、甲戊
Thumbnail
2023/10/22
Drawmind 畫鏡 主要目的是透過藝術治療,幫助個人減輕情感壓力、提升心理健康,並提供一個具有專業指導的平台,讓用戶進行情感表達、自我探索和康復。
Thumbnail
2023/10/22
Drawmind 畫鏡 主要目的是透過藝術治療,幫助個人減輕情感壓力、提升心理健康,並提供一個具有專業指導的平台,讓用戶進行情感表達、自我探索和康復。
Thumbnail
2023/08/14
原理 八字 八字不等於出生時間 八字是根據每個兩小時為一個單位的時辰來劃分的。 它包括年、月、日和時這四個要素,其中年、月、日分別對應天干地支。 即使缺少具體出生時刻,也仍然可以排出命盤進行分析。 紫微斗數 需要精確的出生的小時數,因為出生時間的稍微差異呈現出來的命盤會有天差地別,從而
Thumbnail
2023/08/14
原理 八字 八字不等於出生時間 八字是根據每個兩小時為一個單位的時辰來劃分的。 它包括年、月、日和時這四個要素,其中年、月、日分別對應天干地支。 即使缺少具體出生時刻,也仍然可以排出命盤進行分析。 紫微斗數 需要精確的出生的小時數,因為出生時間的稍微差異呈現出來的命盤會有天差地別,從而
Thumbnail
看更多
你可能也想看
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
Thumbnail
  當我們要使用執行緒的時候,就要引用System.Threading的類別庫,程式才可以使用唷!這篇內容先說明:建立與啟用執行緒、跨執行緒控制UI介面、等待或暫停時間執行緒、共享資源的部分。
Thumbnail
  當我們要使用執行緒的時候,就要引用System.Threading的類別庫,程式才可以使用唷!這篇內容先說明:建立與啟用執行緒、跨執行緒控制UI介面、等待或暫停時間執行緒、共享資源的部分。
Thumbnail
  在說執行緒(Thread)時就要先知道什麼是程式(Program)、程序(Process),才能了解什麼是執行緒(Thread),因為它們間都有著神秘的關係與關聯,再更深入一點就又會有多程序(muti-Process)、多執行緒(muti-Thread),我們就先一一說明好了,了解它們後再使用時
Thumbnail
  在說執行緒(Thread)時就要先知道什麼是程式(Program)、程序(Process),才能了解什麼是執行緒(Thread),因為它們間都有著神秘的關係與關聯,再更深入一點就又會有多程序(muti-Process)、多執行緒(muti-Thread),我們就先一一說明好了,了解它們後再使用時
Thumbnail
這邊要來跟大家介紹C#,使用的軟體會是Visual Studio 2017版本 介紹內容架構可以分六大階段:入門級、基礎級、中低階級、中階級、中高階級、高階級 在正式開始寫程式前,要先了解一些基本概念哦! 就如同學中文前要先了解ㄅㄆㄇㄈ或羅馬拼音之類的,程式也是一樣道理,先把基本概念了解後再來開始
Thumbnail
這邊要來跟大家介紹C#,使用的軟體會是Visual Studio 2017版本 介紹內容架構可以分六大階段:入門級、基礎級、中低階級、中階級、中高階級、高階級 在正式開始寫程式前,要先了解一些基本概念哦! 就如同學中文前要先了解ㄅㄆㄇㄈ或羅馬拼音之類的,程式也是一樣道理,先把基本概念了解後再來開始
Thumbnail
介紹 委派的非同步方法 可以透過BeginInvoke執行委派的非同步方法 Action<T>.BeginInvoke(<T> obj,AsyncCallback callback,Object @object) 第一個內容的 obj,只的是要傳入acction委派的參數 第二個AsyncCallb
Thumbnail
介紹 委派的非同步方法 可以透過BeginInvoke執行委派的非同步方法 Action<T>.BeginInvoke(<T> obj,AsyncCallback callback,Object @object) 第一個內容的 obj,只的是要傳入acction委派的參數 第二個AsyncCallb
Thumbnail
介紹 📷 定義 處理序(Process) (大陸:進程): 一個程序運行時,占用全部計算資源的總和 執行緒(Thread) (大陸:線程):是作業系統能夠進行運算排程的最小單位。 大部分情況下,它被包含在行程之中,是行程中的實際運作單位。 C#多線程和異步(一)——基本概念和使用方法 執行緒帶來的
Thumbnail
介紹 📷 定義 處理序(Process) (大陸:進程): 一個程序運行時,占用全部計算資源的總和 執行緒(Thread) (大陸:線程):是作業系統能夠進行運算排程的最小單位。 大部分情況下,它被包含在行程之中,是行程中的實際運作單位。 C#多線程和異步(一)——基本概念和使用方法 執行緒帶來的
Thumbnail
介紹 計算機架構相關名詞 📷 中央處理器 (CPU)Central Processing Unit Processors (處理器) Sockets (實體插槽) Cores (實體核心) Logical processors (邏輯核心) 超執行緒(HT)Hyper-Threading Tec
Thumbnail
介紹 計算機架構相關名詞 📷 中央處理器 (CPU)Central Processing Unit Processors (處理器) Sockets (實體插槽) Cores (實體核心) Logical processors (邏輯核心) 超執行緒(HT)Hyper-Threading Tec
Thumbnail
行程(進程、process)、執行緒(線程、thread)、上下文切換(context switch)、行程控制塊(PCB)、行程排班(process scheduler)、行程狀態、執行緒模式
Thumbnail
行程(進程、process)、執行緒(線程、thread)、上下文切換(context switch)、行程控制塊(PCB)、行程排班(process scheduler)、行程狀態、執行緒模式
Thumbnail
這一篇文章將會從Microsoft的.NET Class Library開始介紹,在介紹具狀態和不具狀態,以及物件和new關鍵字。
Thumbnail
這一篇文章將會從Microsoft的.NET Class Library開始介紹,在介紹具狀態和不具狀態,以及物件和new關鍵字。
Thumbnail
本篇文章將會介紹C#的基礎構成和字串的使用,若想要更詳細的教學,可以參考前一篇文章,前往Microsoft官方教學學習。
Thumbnail
本篇文章將會介紹C#的基礎構成和字串的使用,若想要更詳細的教學,可以參考前一篇文章,前往Microsoft官方教學學習。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News