IO 密集型場景(數據庫、Web Service、文件讀寫)釋放執行緒,提升吞吐量。ASP.NET MVC 1.0/2.0 缺乏原生支持,需自行擴展。
Route → MvcRouteHandler → MvcHandler → IController.Execute → IActionInvoker.InvokeAction
關鍵切入點:IAsyncController、IAsyncActionInvoker、自定義 MvcRouteHandler。
public abstract class AsyncController : Controller, IAsyncController {
public AsyncManager AsyncManager { get; } = new AsyncManager();
public IAsyncResult BeginExecute(RequestContext context, AsyncCallback callback, object state) {
AsyncManager.OutstandingOperations.Increment();
return base.BeginExecute(context, callback, state);
}
public void EndExecute(IAsyncResult asyncResult) {
base.EndExecute(asyncResult);
AsyncManager.OutstandingOperations.Decrement();
}
}
public class AsyncManager {
public OutstandingOperationsTracker OutstandingOperations { get; } = new OutstandingOperationsTracker();
public IDictionary Parameters { get; } = new Dictionary();
public void Sync(Action action) {
OutstandingOperations.Increment();
ThreadPool.QueueUserWorkItem(_ => {
try { action(); }
finally { OutstandingOperations.Decrement(); }
});
}
}
public class AsyncActionInvoker : ControllerActionInvoker {
protected override ActionResult InvokeActionMethod(ControllerContext ctx, ActionDescriptor desc, IDictionary parameters) {
var asyncController = ctx.Controller as AsyncController;
if (asyncController == null) return base.InvokeActionMethod(ctx, desc, parameters);
var asyncResult = desc.BeginExecute(asyncController, parameters, null, null);
asyncController.AsyncManager.OutstandingOperations.Increment();
return new AsyncActionResult(asyncResult, asyncController.AsyncManager);
}
}
public class AsyncActionResult : ActionResult {
private readonly IAsyncResult _asyncResult;
private readonly AsyncManager _manager;
public override void ExecuteResult(ControllerContext context) {
_manager.OutstandingOperations.Decrement();
// 異步完成後繼續管道...
}
}
public class HomeController : AsyncController {
public void LongRunning() {
AsyncManager.OutstandingOperations.Increment();
Task.Run(() => {
// 耗時操作:數據庫、Web API、文件處理
var data = _service.GetHeavyData();
AsyncManager.Parameters["result"] = data;
AsyncManager.OutstandingOperations.Decrement();
});
}
public ActionResult LongRunningCompleted() {
var data = AsyncManager.Parameters["result"] as HeavyData;
return View(data);
}
}
官方 AsyncController、AsyncManager、MapAsyncRoute 提供規範化實現,建議生產環境直接引用 Microsoft.Web.Mvc。