C# 中的多線程:優點、基礎知識和最佳實踐

已發表: 2023-06-01

目錄

什麼是多線程編程

多線程是軟件工程中的一個基本概念。 在 C# 中,多線程編程對於使用 .NET Framework 的軟件開發人員來說是必不可少的。 開發人員廣泛使用C# 中的多線程,因為它允許他們高效地創建複雜且響應迅速的應用程序。

此博客概述了 C# 多線程,同時還介紹了程序員如何輕鬆創建和管理線程。 它還包括使用多線程和 C# 中可用的不同線程模型的好處。

多線程編程的好處和優點

同時執行時,多線程可提高應用程序的效率。 C# 線程最常見的好處包括:

  • 增強的應用程序性能:在多線程的幫助下,多個任務在同一空間中運行時,應用程序運行速度更快。總的來說,它減少了執行時間並讓位於多個任務。
  • 提高吞吐量: C# 中的多任務處理提高了應用程序的吞吐量。當兩個不同的線程同時運行時,可以節省時間和資源。
  • 改進的響應能力:在多線程的幫助下,用戶可以在程序在後台運行時訪問應用程序的前端。
  • 提高資源利用率:多線程允許用戶更有效地訪問系統資源。例如,線程可以共享文件、內存和 I/O 設備等資源,從而為提高效率鋪平道路。
  • 更易於編程:多線程使編程更容易,因為用戶可以獨立編寫線程。它還使用戶能夠單獨調試和測試應用程序。
  • 優化的通信:線程同步可以實現更好的進程間通信。它可用於線程之間更易於訪問的通信。

首先,它影響可以同步的單個對象。 其次,它可以與 System.Threading 和 Interlocked 類一起使用。

C#中多線程的基本概念

多線程使用戶能夠在多個處理器內核的幫助下同時執行多項任務。 以下是多線程中使用的基本概念:

  • 線程:線程是多線程中幫助執行進程的基本單元。這些是給定程序中的執行路徑,可以與其他線程並發運行。

在C#中,我們可以找到兩種類型的線程,即前台線程和後台線程。 一般的線程類包括名稱、優先級、isAlive、ThreadState、Start()、Suspend()、Resume() 和 Join()。

  • 線程池:線程池是幫助執行任務的線程。它允許操作系統重用現有線程並將可能的開銷風險降至最低。
  • 同步:同步是忽略對多個操作的其他線程的訪問。這是維護數據完整性和防止開銷的重要過程。
  • 死鎖:死鎖是當兩個線程共享資源並嘗試繼續但未成功時發生的錯誤。它可能導致系統凍結甚至導致等待時間。
  • 異步編程:異步編程允許在後台運行多個任務,同時允許主線程不間斷地運行。它為多響應用戶界面鋪平了道路,增強了應用程序性能。

創建和運行線程

使用這些示例可以更輕鬆地創建和運行。 下面給出了一個C# 多線程示例

使用系統;

使用系統線程;

類程序{

靜態無效主要(){

int workerIndex = 0;

線程 workerThread = new Thread(new ThreadStart(Worker));

workerThread.Start();

對於 (int mainIndex = 1; mainIndex <= 10; mainIndex++) {

Console.WriteLine(“主線程:{0}”, mainIndex);

線程.睡眠(200);

}

workerThread.Join();

}

靜態無效工人(){

for (int workerIndex = 1; workerIndex <= 10; workerIndex++) {

Console.WriteLine(“工作線程:{0}”, workerIndex * 2);

線程.睡眠(200);

}

}

}

輸出:

主線程:1

工作線程:2

主線程:2

工作線程:4

主線程:3

工作線程:6

主線程:4

工作線程:8

主線程:5

工作線程:10

主線程:6

工作線程:12

主線程:7

工作線程:14

主線程:8

工作線程:16

主線程:9

工作線程:18

主線程:10

工作線程:20

解釋:在這個輸出中,兩個線程同時打印數字 1 到 10 和 2 到 20,後者從循環索引中加倍。在本示例中,使用了C# 線程休眠(Thread.Sleep) 方法。

同樣的,我們來看另一個使用前台線程的C#線程例子

使用系統;

使用系統線程;

類程序{

靜態無效主要(){

線程 myThread = new Thread(Worker);

我的線程。開始();

Console.WriteLine(“主線程:已啟動”);

對於 (int i = 1; i <= 5; i++) {

Console.WriteLine(“主線程:計數 {0}”, i);

線程.睡眠(500);

}

Console.WriteLine(“主線程:結束”);

}

靜態無效工人(){

對於(j = 1;j <= 5;j++){

Console.WriteLine(“工作線程:計數{0}”, j * 3);

線程.睡眠(750);

}

Console.WriteLine(“工作線程:結束”);

}

}

輸出:

主線程:開始

工作線程:計數 3

主線程:計數 1

工作線程:計數 6

主線程:計數 2

工作線程:計數 9

主線程:計數 3

工作線程:計數 12

主線程:計數 4

工作線程:計數 15

主線程:計數 5

工作線程:已結束

主線程:結束

說明:此輸出顯示兩個線程如何同時工作。由於主線程和後台線程並行工作,主線程打印從 1 到 5 的數字。工作線程打印 3 到 15 的倍數。

查看 upGrad 的軟件開發課程以提高技能。

閱讀我們與軟件開發相關的熱門文章

為什麼要學習編碼? 如何學習編碼? 如何安裝特定版本的 NPM 包? C++ 中的繼承類型 你應該知道什麼?

線程同步

線程同步涉及程序中多個線程的集體協調。 它確保程序以特定順序執行,從而可以訪問共享資源。

在 C# 中,它是使用 lock 關鍵字、同步對象和 Interlocked 類等同步原語完成的。

下面給出一個C#線程同步的例子:

使用系統;

使用系統線程;

類 TablePrinter

{

公共無效打印表()

{

鎖定(這個)

{

對於 (int i = 3; i <= 8; i++)

{

線程.睡眠(200);

控制台.WriteLine(i*5);

}

}

}

}

課程計劃

{

public static void Main(string[] args)

{

TablePrinter tp = new TablePrinter();

Thread t1 = new Thread(new ThreadStart(tp.PrintTable));

Thread t2 = new Thread(new ThreadStart(tp.PrintTable));

t1.開始();

t2.開始();

}

}

輸出:

15

20

25

30

35

40

45

50

55

60

探索我們的軟件開發免費課程

雲計算基礎 從零開始的 JavaScript 基礎 數據結構和算法
區塊鏈技術 初學者反應 核心 Java 基礎知識
爪哇 初學者的 Node.js 高級JavaScript

死鎖

當至少兩個或兩個以上的線程依賴於一組資源時,就會發生多線程死鎖。 當一個線程與求助路徑重疊而另一個線程試圖做同樣的事情時,就會變成死鎖。

例如,如果線程 A 鎖定了資源 1 並正在等待訪問資源 2,而線程 B 正在等待資源 1,則可能會導致死鎖。

下面給出一個例子:

使用系統;

使用系統線程;

命名空間 deadlockincsharp

{

公共課範例

{

靜態只讀對象 firstLock = new object();

靜態只讀對象 secondLock = new object();

靜態無效 ThreadJob()

{

Console.WriteLine(“\t\t\t\tLocking firstLock”);

鎖(firstLock)

{

Console.WriteLine(“\t\t\t\tLocked firstLock”);

線程.睡眠(1500);

Console.WriteLine(“\t\t\t\tLocking secondLock”);

鎖(secondLock)

{

Console.WriteLine(“\t\t\t\tLocked secondLock”);

}

Console.WriteLine(“\t\t\t\t釋放了secondLock”);

}

Console.WriteLine(“\t\t\t\t釋放了第一個鎖”);

}

靜態無效主要()

{

新線程(新線程啟動(ThreadJob))。開始();

線程.睡眠(1000);

Console.WriteLine(“鎖定 secondLock”);

鎖(secondLock)

{

Console.WriteLine(“鎖定secondLock”);

Console.WriteLine("Locking firstLock");

鎖(firstLock)

{

Console.WriteLine("Locked firstLock");

}

Console.WriteLine(“釋放了firstLock”);

}

Console.WriteLine(“釋放了secondLock”);

控制台.Read();

}

}

}

輸出:

加鎖secondLock

鎖定secondLock

先上鎖Lock

先上鎖Lock

釋放第一個鎖

釋放第二個鎖

需求軟件開發技能

JavaScript 課程 核心 Java 課程 數據結構課程
Node.js 課程 課程 全棧開發課程
NFT課程 開發運營課程 大數據課程
React.js 課程 網絡安全課程 雲計算課程
數據庫設計課程 Python 課程 加密貨幣課程

線程池

線程池有助於在 C# 的多線程環境中管理多個執行線程。 這些確保所有線程都可以訪問受控資源而不會引起死鎖。

線程池管理器負責管理線程池,負責創建、銷毀和調度線程。

下面是一個使用 TPL(任務並行庫)的線程池示例:

使用系統;

使用 System.Threading.Tasks;

課程計劃

{

靜態無效主要()

{

任務<字符串> task = Task.Factory.StartNew<字符串>

(() => DownloadString(“http://www.example.com/”));

字符串結果 = task.Result;

控制台.WriteLine(結果);

控制台.Read();

}

靜態字符串 DownloadString(字符串 uri)

{

使用 (var wc = new System.Net.WebClient())

返回 wc.DownloadString(uri);

}

輸出:

輸出取決於網頁上可用的內容。 該程序將確保從指定 URL 的網頁下載內容。 然後它將打印它們。

使用任務並行庫 (TPL) 進行異步編程

任務並行庫 (TPL) 是處理 APIS 和公共類型的強大工具。 它處理System.ThreadingSystem.Threading.Tasks

.NET Framework 4 為旨在編寫並行代碼的開發人員提供了語言和框架級別的 API。 在 TPL 的幫助下,異步編程允許程序在不阻塞主線程的情況下運行。

下面是使用 TPL 進行異步編程的示例:

任務<字符串> task = Task.Factory.StartNew<字符串>(() => {

返回“結果”;

});

字符串結果 = task.Result;

異步任務 MyMethod() {

字符串結果=等待任務;

}

查看我們的免費技術課程,在競爭中脫穎而出。

C# 中多線程的最佳實踐

就性能和多任務處理而言,多線程可以節省時間。 要了解有關多線程如何工作的更多信息,您可以選擇LJMU 的計算機科學理學碩士學位

這裡有一些最佳實踐可以幫助用戶節省時間並記錄最高效率。

  • 利用線程安全的集合: .NET Framework 的並發集合為每個集合提供線程安全的版本,這使得多線程更容易高效地工作。這些集合包括列表和查詢,以及字典。
  • 實現線程同步:由於線程工具的特性,用戶可以快速實現鎖、監視器和信號量。
  • 使用線程池:多線程對於系統來說可以更容易和更有效,這要歸功於用戶完成的絕大多數線程池。同時,用戶可以使用它來自動創建線程。
  • 使用線程本地存儲:在練習多線程時,通過優化線程本地存儲和提供對多個線程的訪問來確保對特定資源的訪問。
  • 避免共享可變狀態:共享可變狀態只會導致錯誤和競爭條件,這可能很棘手。確保不惜一切代價避免可變狀態。
  • 使用異步模型:異步方法可幫助您並行執行多個任務,而無需重新啟動它們或將它們留在隊列中。
  • 避免死鎖:使用多線程執行程序時可能會出現死鎖。編寫程序時,嘗試一個線程接一個線程運行,避免死鎖。
  • 使用取消令牌:取消令牌允許線程無問題地終止並避免死鎖。

探索我們的熱門軟件工程課程

LJMU & IIITB 計算機科學碩士 加州理工學院 CTME 網絡安全證書課程
全棧開發訓練營 區塊鏈PG項目
全棧開發中的執行 PG 計劃
在下面查看我們所有的課程
軟件工程課程

結論

C# 中的多線程仍然是一個基本概念,其高效模型正在發揮作用。 它為程序員提供了一種靈活的方式,可以將程序的工作負載劃分為多個並發且獨立運行的任務。

雖然多線程可能非常有益,但如果不小心實施,它可能會導致潛在的障礙。

2009 年至 2023 年間,全球用於企業軟件的預算超過8560 億美元,軟件開發為開發人員帶來了光明的職業生涯。

立即申請upGrad 的全棧軟件開發訓練營 全棧開發課程可以成為想要釋放計算機科學潛力的開發人員的墊腳石。

1.什麼是多線程編程?

多線程編程是涉及同時使用多個線程執行程序的過程。 它使前端用戶可以不間斷地使用計算機上運行的程序的多個副本。

2. 線程和進程的主要區別是什麼?

進程通常涉及處於執行狀態的程序,而線程由子進程中的進程組成。

3. C#中線程和任務有什麼區別?

C# 中的線程負責構建和管理用於編程的線程池。 另一方面,任務表示在後台運行的異步函數。