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

ASP.NET 同步非同步呼叫實戰:使用 AutoResetEvent 協調執行緒

     編輯:關於ASP.NET

當第三方程式庫僅提供非同步 API (如 XMPP 連線庫),但 ASP.NET 頁面生命週期為同步模式時,需將非同步作業同步化:頁面呈現前必須完成回呼驗證。

問題情境

XmppClientConnection.Open() 立即返回,登入/註冊在背景執行緒進行,成功觸發回呼事件。若直接呼叫,頁面會先渲染,回呼才稍後執行,違反業務邏輯。

方案演進:從 Monitor 到 AutoResetEvent

❌ Monitor 失敗嘗試

private object objlock = new object();
public void RegisterJab(...)
{
    Monitor.Enter(objlock);
    _connection.Open();
    Monitor.Wait(objlock);  // 等待回呼釋放
    _connection.Close();
}

private void XmppCon_OnRegistered(object sender)
{
    IsSuccessfull = true;
    Monitor.Exit(objlock);  // 拋出 SynchronizationLockException!
}

失敗原因:回呼在不同執行緒 (Jabber 輔助執行緒),非鎖定擁有者,無法呼叫 Monitor.Exit。

✅ AutoResetEvent 成功方案

AutoResetEvent 專為執行緒間訊號通知設計,允許非擁有者執行緒發送訊號。

public class Register
{
    private XmppClientConnection _connection;
    private static AutoResetEvent _resetEvent;
    public bool IsSuccessfull = false;
    public bool IsUsed = false;

    public Register()
    {
        _connection = new XmppClientConnection();
        _connection.OnLogin += XmppCon_OnLogin;
        _connection.OnRegisterError += XmppCon_OnRegErr;
        _connection.OnRegistered += XmppCon_OnRegistered;
    }

    public void RegisterJab(string username, string password, string server)
    {
        // 設定連線參數...
        _resetEvent = new AutoResetEvent(false); // 非終止狀態
        _connection.Open();
        
        // 阻塞 ASP.NET 執行緒,最多等待 20 秒
        _resetEvent.WaitOne(20 * 1000, true); 
        
        _connection.Close();
    }

    private void XmppCon_OnRegistered(object sender)
    {
        IsSuccessfull = true;
        _resetEvent.Set(); // 發送訊號,喚醒主執行緒
    }

    private void XmppCon_OnLogin(object sender)
    {
        IsSuccessfull = true;
        _resetEvent.Set();
    }

    private void XmppCon_OnRegErr(object sender, Element e)
    {
        IsSuccessfull = false;
        if (e.SelectSingleElement("error").Attribute("code") == "409")
            IsUsed = true; // 用戶已存在
        _resetEvent.Set();
    }
}

關鍵差異比較

機制MonitorMutexAutoResetEvent
跨執行緒釋放❌ 僅擁有者✅ 可跨執行緒✅ 專為訊號設計
語意互斥鎖互斥體事件訊號
適用場景關鍵區段跨進程同步執行緒協調/等待

核心模式

  1. 建立 new AutoResetEvent(false) - 非受信狀態
  2. 啟動非同步作業
  3. 主執行緒 WaitOne(timeout) 阻塞等待
  4. 回呼執行緒完成時呼叫 Set() 釋放
  5. 主執行緒繼續執行後續邏輯

此模式完美解決「非同步庫同步化」需求,確保業務邏輯順序正確。

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