首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 多執行緒程式設計入門指南

     編輯:關於.NET

簡介

多執行緒是建構大型系統時必須重點關注的關鍵技術,尤其在效率(系統跑多快?)與效能(系統運作是否正常?)之間取得平衡時。恰當運用多執行緒能大幅提升系統效能。

什麼是執行緒?

系統上每個正在執行的程式都是一個行程。每個行程包含一到多個執行緒。行程也可以是整個程式或部分程式的動態執行。執行緒是一組指令的集合,或程式的特定區段,能在程式內獨立執行,也可視為程式碼執行的上下文。因此執行緒本質上是輕量級行程,負責在單一程式內實現多工。通常由作業系統負責多執行緒的排程與執行。

什麼是多執行緒?

多執行緒旨在讓多個執行緒並行工作以完成多項任務,提升系統效率。當同一時間需要完成多項任務時,便會實現多執行緒。

使用執行緒的優點

  • 將耗時長的任務放到背景處理,避免阻塞主執行緒。
  • 使用者介面更友善:例如點擊按鈕觸發事件時,可顯示進度條顯示處理進度。
  • 程式執行速度可能加快(多核心環境下)。
  • 在等待型任務(使用者輸入、檔案讀寫、網路收發)中,執行緒能釋放寶貴資源(如記憶體佔用)。

執行緒模型背景(Win32 環境)

單執行緒模型

一個行程僅能有一個執行緒,其餘行程必須等待當前執行緒結束。缺點:完成微小任務也需佔用極長時間。

單執行緒單元模型(STA, Single Threaded Apartment)

一個程式可包含多個執行緒,每個執行緒被劃分為行程內的一個單元。行程可包含多個單元,可共享單元間資料。所有請求透過 Windows 訊息佇列序列化,確保同一時間僅存取一個單元,故同一時間僅有一個執行緒執行。優於單執行緒模型可同時響應多用戶請求,但因序列化導致效能仍非最佳。

多執行緒單元模型(MTA, Multi-threaded Apartment / Free-threaded)

每個行程只有一個單元,但該單元控制多個執行緒。無需訊息佇列,所有執行緒屬於同一單元可直接共享資料。執行速度優於 STA,降低系統負載、減少閒置時間。但程式複雜度較高,開發者需自行提供執行緒同步機制(如鎖)避免競爭條件,且可能導致死結。

.NET 中的多執行緒運作方式

.NET 本質上是多執行緒環境,提倡兩種主要方式:

  1. 使用 ThreadStart 建立自有執行緒(手動管理)。
  2. 直接(ThreadPool.QueueUserWorkItem)或間接(如 Stream.BeginRead、BeginInvoke)使用執行緒集區(ThreadPool)。

一般建議:長時間執行的任務手動建立新執行緒;短時間、頻繁啟動的任務優先使用執行緒集區。集區可同時執行多項任務、善用框架類別,並在資源稀缺需同步時限制同一時間僅允許單一執行緒存取資源(實現鎖機制)。執行緒基底類別為 System.Threading,所有執行緒透過 CLI 管理。

核心操作

建立執行緒

Thread dummyThread = new Thread(new ThreadStart(DummyFunction));

啟動執行緒

dummyThread.Start();

等待執行緒結束

dummyPriorityThread.Join();

暫停執行緒

dummyPriorityThread.Sleep(<毫秒數>);

中止執行緒

dummyPriorityThread.Abort();

同步機制

常見同步方式包括:

  • Interlocked 類別:提供原子操作實現鎖機制,如 Interlocked.Increment(ref counter)。
  • lock 關鍵字:鎖定關鍵程式碼區塊,lock(this) { ... }。
  • Monitor 類別:Monitor.Enter(this) 等進階控制。

以下範例展示基本同步情境:

using System;
using System.Threading;

namespace SynchronizationThreadsExample
{
    class SynchronizationThreadsExample
    {
        private int counter = 0;
        static void Main()
        {
            var STE = new SynchronizationThreadsExample();
            STE.ThreadFunction();
        }
        public void ThreadFunction()
        {
            Thread dummyThread = new Thread(new ThreadStart(SomeFunction));
            dummyThread.IsBackground = true;
            dummyThread.Name = "First Thread";
            dummyThread.Start();
            Console.WriteLine("Started thread {0}", dummyThread.Name);

            Thread dummyPriorityThread = new Thread(new ThreadStart(SomeFunction));
            dummyPriorityThread.IsBackground = true;
            dummyPriorityThread.Name = "Second Thread";
            dummyPriorityThread.Start();
            Console.WriteLine("Started thread {0}", dummyPriorityThread.Name);

            dummyThread.Join();
            dummyPriorityThread.Join();
        }
        public void SomeFunction()
        {
            try
            {
                while (counter < 10)
                {
                    int tempCounter = counter;
                    tempCounter++;
                    Thread.Sleep(1);
                    counter = tempCounter;
                    Console.WriteLine("Thread {0}. SomeFunction: {1}", Thread.CurrentThread.Name, counter);
                }
            }
            catch (ThreadInterruptedException ex)
            {
                Console.WriteLine("Exception in thread {0}", Thread.CurrentThread.Name);
            }
            finally
            {
                Console.WriteLine("Thread {0} Exiting.", Thread.CurrentThread.Name);
            }
        }
    }
}

執行緒的缺點

  • 大量執行緒會因作業系統頻繁切換而影響效能。
  • 更多執行緒需要更多記憶體空間。
  • 執行緒增加程式錯誤風險,需謹慎使用。
  • 執行緒中止需考慮對程式執行的影響。
  • 單元模型下資料常在多執行緒間共享,需完善的鎖機制取代直接資料共享。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved