一、新建空的WEB項目最好是.net4.5。

二、新建一個一般處理程序,修改IHttpHandler為HttpTaskAsyncHandler,然后敲入如下代碼,開始執行。
/// <summary> /// AsyncHandler 的摘要說明 /// </summary> public class AsyncHandler : HttpTaskAsyncHandler { public async override Task ProcessRequestAsync(HttpContext context) { System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); sw.Reset(); sw.Restart(); context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " 開始異步ProcessRequestAsync"); context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " 創建異步執行代碼任務,並設置任務耗時10000。"); var task = ExecuteTask(context, 10000); context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " 創建異步執行代碼任務,並設置任務耗時20000。"); var task2 = ExecuteTask(context, 20000); context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " 繼續執行代碼,並等待3秒。"); System.Threading.Thread.Sleep(3000); context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " 開始等待結果的返回。"); var result = await task; context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " [10000的任務]已經返回。"); var result2 = await task2; context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " [20000的任務]已經返回。"); sw.Stop(); context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " 全部執行完成。總共用時:" + sw.ElapsedMilliseconds + "ms"); } public async Task<string> ExecuteTask(HttpContext context, int time) { context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " ["+ time + "的任務]進入ExecuteTask,將StartNewTask。"); var task = Task.Factory.StartNew<string>(InnerTask, new { time = time, context = context }); context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " [" + time + "的任務]創建任務完成,並已開始異步執行,這里將等5秒。"); System.Threading.Thread.Sleep(5000); context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " [" + time + "的任務]5秒等待完成,將取得結果。"); var result = await task; context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " [" + time + "的任務]取得結果完成。"); return result; } public string InnerTask(dynamic args) { args.context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " [" + args.time + "的任務]InnerTask已進入"); System.Threading.Thread.Sleep(args.time); args.context.Response.Write(DateTime.Now.ToString("\r\nHH:mm:ss") + " [" + args.time + "的任務]InnerTask執行完成,將返回結果。"); return ""; } public override void ProcessRequest(HttpContext context) { base.ProcessRequest(context); } }
三、運行效果。
瀏覽器上輸入:http://localhost:39510/handler/asynchandler.ashx
11:26:52 開始異步ProcessRequestAsync 11:26:52 創建異步執行代碼任務,並設置任務耗時10000。 11:26:52 [10000的任務]進入ExecuteTask,將StartNewTask。 11:26:52 [10000的任務]創建任務完成,並已開始異步執行,這里將等5秒。 11:26:52 [10000的任務]InnerTask已進入 11:26:57 [10000的任務]5秒等待完成,將取得結果。 11:26:57 創建異步執行代碼任務,並設置任務耗時20000。 11:26:57 [20000的任務]進入ExecuteTask,將StartNewTask。 11:26:57 [20000的任務]創建任務完成,並已開始異步執行,這里將等5秒。 11:26:57 [20000的任務]InnerTask已進入 11:27:02 [20000的任務]5秒等待完成,將取得結果。 11:27:02 繼續執行代碼,並等待3秒。 11:27:02 [10000的任務]InnerTask執行完成,將返回結果。 11:27:05 開始等待結果的返回。 11:27:05 [10000的任務]取得結果完成。 11:27:05 [10000的任務]已經返回。 11:27:17 [20000的任務]InnerTask執行完成,將返回結果。 11:27:17 [20000的任務]取得結果完成。 11:27:17 [20000的任務]已經返回。 11:27:17 全部執行完成。總共用時:25003ms
四、結果分析:

圖中是爭對10000ms的任務的分析。所以說,異步Task在StartNew時,或者調用async的方法時,方法體已經開始使用異步執行。當方法體中遇到耗時長的代碼(如Thread.Sleep()或另一個任務的await方法)時,主任務將繼續向下執行,這個新任務同樣也將異步往下執行。當遇到await時,將相繼等待任務中的任務執行完成。當最終執行完成時,將返回結果。如果任務提前完成,將存到Task的Result屬性中,當await這個Task時,將直接返回這個結果。
