玩轉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
留言分享你的想法!
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
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
「欸!這是在哪裡買的?求連結 🥺」 誰叫你太有品味,一發就讓大家跟著剁手手? 讓你回購再回購的生活好物,是時候該介紹出場了吧! 「開箱你的美好生活」現正召喚各路好物的開箱使者 🤩
Thumbnail
介紹朋友新開的蝦皮選物店『10樓2選物店』,並分享方格子與蝦皮合作的分潤計畫,註冊流程簡單,0成本、無綁約,推薦給想增加收入的讀者。
Thumbnail
介紹朋友新開的蝦皮選物店『10樓2選物店』,並分享方格子與蝦皮合作的分潤計畫,註冊流程簡單,0成本、無綁約,推薦給想增加收入的讀者。
Thumbnail
當你邊吃粽子邊看龍舟競賽直播的時候,可能會順道悼念一下2300多年前投江的屈原。但你知道端午節及其活動原先都與屈原毫無關係嗎?這是怎麼回事呢? 本文深入探討端午節設立初衷、粽子、龍舟競渡與屈原自沉四者。看完這篇文章,你就會對端午、粽子、龍舟和屈原的四角關係有新的認識喔。那就讓我們一起解開謎團吧!
Thumbnail
當你邊吃粽子邊看龍舟競賽直播的時候,可能會順道悼念一下2300多年前投江的屈原。但你知道端午節及其活動原先都與屈原毫無關係嗎?這是怎麼回事呢? 本文深入探討端午節設立初衷、粽子、龍舟競渡與屈原自沉四者。看完這篇文章,你就會對端午、粽子、龍舟和屈原的四角關係有新的認識喔。那就讓我們一起解開謎團吧!
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關鍵字。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News