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

更新於 發佈於 閱讀時間約 12 分鐘

介紹

定義

處理序(Process) (大陸:進程): 一個程序運行時,占用全部計算資源的總和
執行緒(Thread) (大陸:線程):是作業系統能夠進行運算排程的最小單位。 大部分情況下,它被包含在行程之中,是行程中的實際運作單位。

執行緒帶來的負擔

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;
};
}

參考資料

本篇已同步發表至個人部落格
https://moushih.com/2022ithome19/
我的鐵人賽文章列表
為什麼會看到廣告
avatar-img
8會員
39內容數
我是這個部落格的作者,喜歡分享有關投資 💰、軟體開發 💻、占卜 🔮 和虛擬貨幣 🚀 的知識和經驗。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
一代軍師 的其他內容
介紹 計算機架構相關名詞 📷 中央處理器 (CPU)Central Processing Unit Processors (處理器) Sockets (實體插槽) Cores (實體核心) Logical processors (邏輯核心) 超執行緒(HT)Hyper-Threading Tec
Array 在記憶體中連續分配,而且元素類型是一樣的,長度不變 優點:讀取快,可以使用座標訪問 缺點:新增、刪除慢 記憶體: 📷 範例程式碼: ArrayList 不定長度,在記憶體中連續分配的,元素沒有類型限制,任何元素都是當成object處理,如果是值類型,會有裝箱的操作 優點:讀取快 缺點:
介紹 這章節純看智商 不可逆加密:原文加密後變成密文,但密文沒辦法解密文回原文 可逆加密:原文加密過後的密文,可以在將密文解密回原文 對稱:表示加解密是否使用同一個key MD5 不可逆加密 MD5 使用的命名空間是 System.Security.Cryptography MD5是一種公開的算法
環境安裝 這邊可以先安裝Expression Tree Visualizer工具 Viusla studio 2019 安裝方式: 檔案(ExpressionTreeVisualizer.2019)下載完之後,將檔案複製到此目錄: C:\Program Files (x86)\Microsoft V
環境準備 準備用測試資料 語法說明 Where 應用場景:過濾、查詢等功能 說明:與SQL命令中的where功能相似,都是過濾範圍內的數值 例如:使用where篩選,年紀大於30的同學 First 應用場景:篩選出第一筆資料,但資料如果是空的會跳Exception 說明:返回集合中的第一個元素,其實
介紹 LINQ全名是(Language-Integrated Query),是一組以直接將查詢功能整合至C# 語言為基礎之技術的名稱。 大家可以想像SQL有SQL的查詢語法,MySql有MySql的查詢語法,但我們可以只透過LINQ語法,C#會自動幫我們轉換成對應的資料庫查詢語法,有點像是秦始皇統一
介紹 計算機架構相關名詞 📷 中央處理器 (CPU)Central Processing Unit Processors (處理器) Sockets (實體插槽) Cores (實體核心) Logical processors (邏輯核心) 超執行緒(HT)Hyper-Threading Tec
Array 在記憶體中連續分配,而且元素類型是一樣的,長度不變 優點:讀取快,可以使用座標訪問 缺點:新增、刪除慢 記憶體: 📷 範例程式碼: ArrayList 不定長度,在記憶體中連續分配的,元素沒有類型限制,任何元素都是當成object處理,如果是值類型,會有裝箱的操作 優點:讀取快 缺點:
介紹 這章節純看智商 不可逆加密:原文加密後變成密文,但密文沒辦法解密文回原文 可逆加密:原文加密過後的密文,可以在將密文解密回原文 對稱:表示加解密是否使用同一個key MD5 不可逆加密 MD5 使用的命名空間是 System.Security.Cryptography MD5是一種公開的算法
環境安裝 這邊可以先安裝Expression Tree Visualizer工具 Viusla studio 2019 安裝方式: 檔案(ExpressionTreeVisualizer.2019)下載完之後,將檔案複製到此目錄: C:\Program Files (x86)\Microsoft V
環境準備 準備用測試資料 語法說明 Where 應用場景:過濾、查詢等功能 說明:與SQL命令中的where功能相似,都是過濾範圍內的數值 例如:使用where篩選,年紀大於30的同學 First 應用場景:篩選出第一筆資料,但資料如果是空的會跳Exception 說明:返回集合中的第一個元素,其實
介紹 LINQ全名是(Language-Integrated Query),是一組以直接將查詢功能整合至C# 語言為基礎之技術的名稱。 大家可以想像SQL有SQL的查詢語法,MySql有MySql的查詢語法,但我們可以只透過LINQ語法,C#會自動幫我們轉換成對應的資料庫查詢語法,有點像是秦始皇統一
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本篇文章探討作業系統如何管理程式,介紹了 Process、Thread 及 Process Control Block(PCB)的基本概念。本文以實際例子解釋這些概念,並詳細說明 Context Switch 的運作方式以及程式的五大狀態。
Thumbnail
避免 thread 競速(Race Condition)是多執行緒編程中常見的挑戰之一。 Race Condition 發生在多個執行緒同時訪問和修改共享資源時,因為執行緒之間的執行順序無法預測,可能會導致數據的不一致性或意外行為。 本文主要介紹如何使用Lock來避免此狀況出現。 首先先看沒
“所有人寫的程式會變成指令 每一道指令是由CPU執行 而CPU所能理解的指令類型有限”
Thumbnail
簡要說明 JavaScript 的 Event Loop JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blo
Thumbnail
本章講述了C#開發中的程序集,命名空間和 NuGet 包管理器。程序集是 .NET 應用的基礎,命名空間用於組織和預防命名衝突,而 NuGet 用於管理 .NET 的外部庫和依賴項。
Thumbnail
本文是C#入門教程的一部分,涵蓋了流程控制的各種語句與迴圈。這包括if、else if和else語句,三元運算子,switch語句,以及for、foreach和while迴圈。文中還介紹了如何在迴圈中使用break、continue、return和goto語句。
Thumbnail
C#程式由一或多個檔案組成,包含命名空間、類別、結構、介面、列舉和委派等型別。Main方法是C#應用程式的進入點。在C#中,註解用於在程式碼中添加說明,有單行和多行兩種類型。變數的定義需要指定變數的類型和名稱,可以一次為多個變數賦值。
※ 同步概念: 單純地「由上而下」執行程式碼,而且一次只執行一件事,也就是「按順序執行,一個動作結束才能切換到下一個」。缺點是你需要「等待」事情執行完畢,才能繼續往下走。 ※ 非同步概念: 盡可能讓主要的執行程序不需要停下來等待,若遇到要等待的事情,就發起一個「非同步處理」,讓主程序繼續執行,
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
Thumbnail
關於多執行緒/多行程的使用方式 在Python 3.2版本之後加入了「concurrent.futures」啟動平行任務, 它可以更好的讓我們管理多執行緒/多行程的應用場景,讓我們在面對這種併發問題時可以不必害怕, 用一個非常簡單的方式就能夠處裡, 底下我們將為您展示一段程式碼: imp
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
本篇文章探討作業系統如何管理程式,介紹了 Process、Thread 及 Process Control Block(PCB)的基本概念。本文以實際例子解釋這些概念,並詳細說明 Context Switch 的運作方式以及程式的五大狀態。
Thumbnail
避免 thread 競速(Race Condition)是多執行緒編程中常見的挑戰之一。 Race Condition 發生在多個執行緒同時訪問和修改共享資源時,因為執行緒之間的執行順序無法預測,可能會導致數據的不一致性或意外行為。 本文主要介紹如何使用Lock來避免此狀況出現。 首先先看沒
“所有人寫的程式會變成指令 每一道指令是由CPU執行 而CPU所能理解的指令類型有限”
Thumbnail
簡要說明 JavaScript 的 Event Loop JavaScript 是單執行緒 (single-threaded) 語言,這意味著它一次只能執行一件事,因此所有函式都需要排隊等待執行,這被稱為同步 (synchronous)。在同步操作中,若函式過多或過於複雜,會導致程式阻塞 (blo
Thumbnail
本章講述了C#開發中的程序集,命名空間和 NuGet 包管理器。程序集是 .NET 應用的基礎,命名空間用於組織和預防命名衝突,而 NuGet 用於管理 .NET 的外部庫和依賴項。
Thumbnail
本文是C#入門教程的一部分,涵蓋了流程控制的各種語句與迴圈。這包括if、else if和else語句,三元運算子,switch語句,以及for、foreach和while迴圈。文中還介紹了如何在迴圈中使用break、continue、return和goto語句。
Thumbnail
C#程式由一或多個檔案組成,包含命名空間、類別、結構、介面、列舉和委派等型別。Main方法是C#應用程式的進入點。在C#中,註解用於在程式碼中添加說明,有單行和多行兩種類型。變數的定義需要指定變數的類型和名稱,可以一次為多個變數賦值。
※ 同步概念: 單純地「由上而下」執行程式碼,而且一次只執行一件事,也就是「按順序執行,一個動作結束才能切換到下一個」。缺點是你需要「等待」事情執行完畢,才能繼續往下走。 ※ 非同步概念: 盡可能讓主要的執行程序不需要停下來等待,若遇到要等待的事情,就發起一個「非同步處理」,讓主程序繼續執行,
Thumbnail
當你需要在 Python 中執行多個任務,但又不希望它們相互阻塞時,可以使用 threading 模組。 threading 模組允許你在單個程序中創建多個執行緒,這些執行緒可以同時運行,從而實現並行執行多個任務的效果。
Thumbnail
關於多執行緒/多行程的使用方式 在Python 3.2版本之後加入了「concurrent.futures」啟動平行任務, 它可以更好的讓我們管理多執行緒/多行程的應用場景,讓我們在面對這種併發問題時可以不必害怕, 用一個非常簡單的方式就能夠處裡, 底下我們將為您展示一段程式碼: imp