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

ASP.NET 自訂非同步 HTTP 處理程式 完整教學

     編輯:ASP.NET 基礎

為什麼需要非同步 Handler?

同步 Handler 每請求佔用一執行緒。高併發、長時間 I/O (資料庫、Web Service、檔案) 會耗盡執行緒池。非同步 Handler 釋放執行緒等待 I/O 完成,再由完成通知繼續處理,大幅提升併發吞吐量。

核心介面:IHttpAsyncHandler + IAsyncResult

1. 實作 IHttpAsyncHandler

using System;
using System.Web;
using System.Threading;

public class AsyncHttpHandler : IHttpAsyncHandler
{
    public bool IsReusable => false;

    // 同步方法不會被呼叫,但必須實作
    public void ProcessRequest(HttpContext context)
    {
        throw new InvalidOperationException("Use async version");
    }

    // 開始非同步處理
    public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
    {
        context.Response.Write("

AsyncHttpHandler Started

"); // 建立實作 IAsyncResult 的狀態物件 var asyncOp = new AsyncOperation(context, cb, extraData); asyncOp.StartAsyncWork(); // 啟動背景工作 return asyncOp; // 立即回傳,釋放執行緒 } // 非同步完成時呼叫 public void EndProcessRequest(IAsyncResult result) { // 這裡通常不需要寫入回應,因背景工作已寫入 // 若需最終處理可在這裡進行 } }

2. 實作 IAsyncResult (AsyncOperation.cs)

using System;
using System.Web;
using System.Threading;

public class AsyncOperation : IAsyncResult
{
    private readonly HttpContext _context;
    private readonly AsyncCallback _callback;
    private readonly object _state;
    private bool _completed;

    public AsyncOperation(HttpContext context, AsyncCallback callback, object state)
    {
        _context = context;
        _callback = callback;
        _state = state;
        _completed = false;
    }

    // IAsyncResult 介面實作
    public object AsyncState => _state;
    public WaitHandle AsyncWaitHandle => null; // 簡易實作回傳 null
    public bool CompletedSynchronously => false;
    public bool IsCompleted => _completed;

    // 啟動背景工作 (使用 ThreadPool)
    public void StartAsyncWork()
    {
        ThreadPool.QueueUserWorkItem(StartAsyncTask);
    }

    private void StartAsyncTask(object state)
    {
        // 模擬耗時 I/O (如資料庫查詢、Web API 呼叫)
        Thread.Sleep(2000); 
        
        // 直接向 Response 寫入結果 (注意:此時已非原始請求執行緒)
        _context.Response.Write($"

Completed on ThreadPool: {Thread.CurrentThread.IsThreadPoolThread}

"); _completed = true; _callback(this); // 通知 ASP.NET 非同步完成,觸發 EndProcessRequest } }

3. Web.config 註冊

<httpHandlers>
  <add verb="*" path="*.async" type="AsyncHttpHandler" />
</httpHandlers>

4. IIS 綁定 (同同步 Handler)

處理常式對應 -> 加入指令碼對應 -> 路徑 *.async -> 執行檔 aspnet_isapi.dll。

5. 測試

瀏覽 https://localhost/YourApp/test.async,頁面先顯示「Started」,2 秒後顯示「Completed on ThreadPool: True」,且期間不阻塞執行緒。

關鍵概念解析

概念說明
BeginProcessRequest快速啟動非同步工作,立即回傳 IAsyncResult,釋放 IIS 執行緒。
ThreadPool.QueueUserWorkItem將工作排入執行緒池,由背景執行緒執行耗時邏輯。
AsyncCallback工作完成時呼叫,通知 ASP.NET 執行管線喚醒請求繼續。
EndProcessRequest管線喚醒後呼叫,可做最後收尾 (如釋放資源),回應通常已在背景寫入。
IAsyncResult.IsCompleted供輪詢查詢進度 (少用),主要靠 Callback 驅動。

進階:共用資源與同步

背景執行緒存取共用資料 (快取、靜態變數) 需加鎖 (lock, Monitor, ConcurrentDictionary) 或使用 WaitHandle (如 ManualResetEvent) 協調。簡易範例中 AsyncWaitHandle 回傳 null,生產環境建議實作完整 WaitHandle 以支援 WaitOne 等待。

現代替代方案:ASP.NET Core / async/await

ASP.NET Core 內建支援 async/await,Controller Action 直接 public async Task Get(),無需手動實作 IHttpAsyncHandler。若維護舊版 Web Forms,非同步 Handler 仍是提升併發的有效手段。

總結

非同步 HTTP Handler 實作 IHttpAsyncHandler + IAsyncResult,利用 ThreadPool 執行耗時工作,釋放 IIS 執行緒。核心流程:BeginProcessRequest 啟動 -> 背景工作 -> AsyncCallback 通知 -> EndProcessRequest 收尾。適合 I/O 密集型高併發場景。

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