異步一般處理程序的用法


一、新建空的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時,將直接返回這個結果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM