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

.NET 非同步機制深度解析 (五):執行緒間通訊 — SynchronizationContext、AsyncOperation 與 WinForm 實戰

     編輯:關於.NET

非同步作業完成後,必須將結果安全地傳回 UI 執行緒更新介面。本文系統解析 .NET 三代執行緒通訊機制:ISynchronizeInvoke (1.0)、SynchronizationContext (2.0)、AsyncOperation/AsyncOperationManager (2.0+),並給出 WinForm 與 Console 完整實戰範例。

核心問題:跨執行緒存取 UI 控制項

WinForm 控制項具有執行緒親和性,背景執行緒直接設定 Label.Text 會拋出 InvalidOperationException:「執行緒間操作無效」。

第一代:ISynchronizeInvoke (Control 實作)

  • InvokeRequired:判斷呼叫端是否為 UI 執行緒。
  • Invoke(delegate, args):同步封送,阻塞呼叫端直到 UI 執行緒完成。
  • BeginInvoke/EndInvoke:非同步封送,不阻塞呼叫端。
ISynchronizeInvoke sync = this.listBox1;
if (sync.InvokeRequired)
    sync.Invoke(new Action<string>(AddLog), "訊息");
else
    AddLog("訊息");

第二代:SynchronizationContext (統一抽象)

WinForm 啟動時自動建立 WindowsFormsSynchronizationContext;Console 需手動 new SynchronizationContext()。兩大核心方法:

  • Send(SendOrPostCallback, state):同步 (對應 Invoke)。
  • Post(SendOrPostCallback, state):非同步,內部使用 ThreadPool.QueueUserWorkItem (對應 BeginInvoke)。

WinForm 範例

// UI 執行緒取得 context
SynchronizationContext ctx = SynchronizationContext.Current;
DoWork.BeginInvoke(OnComplete, ctx);

// 背景執行緒回呼
void OnComplete(IAsyncResult ar)
{
    SynchronizationContext ctx = (SynchronizationContext)ar.AsyncState;
    ctx.Post(_ => listBox.Items.Add("完成"), null);
}

Console 範例 (手動建立 context)

var ctx = new SynchronizationContext();
new Thread(o => {
    var ui = (SynchronizationContext)o;
    ui.Post(_ => Console.WriteLine("來自背景執行緒"), null);
}).Start(ctx);

第三代:AsyncOperation / AsyncOperationManager (元件模型友善)

封裝 SynchronizationContext,自動捕獲建立時的 context,提供 Post 與 OperationCompleted (通知完成,供元件設計師追蹤)。

public class Worker
{
    private AsyncOperation op = AsyncOperationManager.CreateOperation(null);
    public event EventHandler WorkDone;

    public void Start()
    {
        new Thread(DoWork).Start();
    }

    private void DoWork()
    {
        op.Post(_ => WorkDone?.Invoke(this, EventArgs.Empty), null);
        op.OperationCompleted(); // 重要:通知操作結束
    }
}

比較總結

機制適用場景優點缺點
ISynchronizeInvokeWinForm 快速修補直接用 Control.Invoke緊耦合 UI、無法單元測試
SynchronizationContext跨平台、庫開發抽象化、支援 Console/ASP.NET/WPF手動傳遞 context
AsyncOperation元件開發、BackgroundWorker 替代自動捕獲 context、支援取消/進度稍顯繁瑣

執行緒通訊原理圖 跨執行緒例外示意 ISynchronizeInvoke 實作結果 SynchronizationContext.Current 差異 Post 非同步執行緒池行為 跨執行緒例外 ISynchronizeInvoke 實作結果2 SynchronizationContext.Current 差異2 Post 非同步執行緒池行為2

建議:新專案優先使用 SynchronizationContext 或 Task/async-await (現代模式);維護舊代碼時理解三代演進有助於正確重構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved