在MVC中使用async和await的说明

首先,在mvc中若是要用纯异步请不要使用async和await,能够直接使用Task.Run。web

其次,在mvc中使用async和await可让系统开新线程处理Task的代码,同时没必要等Task执行结束,就能够同时运行Task以后的代码,加快效率。数据库

要注意的是:若是使用async和await,系统虽然能够同时处理多个事务,但客户端(浏览器)不会有响应,依然要等到全部代码所有执行完毕(包括异步的代码)才能正常响应。编程

/*
 * 演示如何利用 .net 4.5 的新特性实现异步操做
 * 
 * 什么场景下须要异步操做?
 * 在由于磁盘io或网络io而致使的任务执行时间长的时候应该使用异步操做,若是任务执行时间长是由于cpu的消耗则应使用同步操做(此时异步操做不会改善任何问题)
 * 原理是什么?
 * 在 Web 服务器上,.NET Framework 维护一个用于服务 ASP.NET 请求的线程池(如下把 .NET Framework 维护的用于服务 ASP.NET 请求的线程池称做为“特定线程池”)
 * 同步操做时,若是特定线程池利用满了,则不会再提供服务
 * 异步操做时:
 * 一、一个请求过来,特定线程池出一个线程处理此请求
 * 二、启动一个非特定线程池中的另外一个线程处理异步操做,此时处理此请求的线程就会空出来,不会被阻塞,它能够继续处理其它请求
 * 三、异步操做执行完毕后,从特定线程池中随便找一个空闲线程返回请求结果
 */

 

实际工做中,async和await咱们能够用于相似用户上传头像、上传照片这种的耗时较长的功能中,咱们能够在边上传照片时边处理数据库的其余事务。浏览器

而纯异步则多用于时间较长,而无需结果实时看反馈给用户的操做,例如:管理在后台备份数据库、清理垃圾文件等。服务器

若是async和await的异步方法是有返回值的,并且主方法中又要使用这个返回值,那么将不会实现多个异步方法同时执行,要等异步结果后才继续执行,至关于异步并未起到多程序同时处理事务的目的。这仅是对于Web或控制台程序而言的,若是对于Winform则有大大的不一样,由于Winform若是使用异步时界面是能够响应的。网络

Web中异步更多的是用来实现大量IO操做,或大量调用WCF、WebService时使用。多线程

因此,在Mvc这种Web界面中使用async和await异步的实际意义就不是很大了,由于界面老是没有响应的,并且也没法实现多线程同时工做。mvc

有须要请看这篇:http://www.dozer.cc/2012/03/async-and-await-in-web-application/app

async的做用是异步执行,await的做用是等待执行结果(会卡住异步方法中await如下的代码,但不会卡死主线程)。
异步

async通常最终都须要一个async void方法来进行最高层的调用。好比:private async void Sync_Button_Click(object sender, RoutedEventArgs e),C#中也提供了大量的可设置async的系统方法和事件。

 

class Program  
{  
    private static async void Test()  
    {  
        Task<int> t = new Task<int>(() => { Thread.Sleep(3000); return 1; });  
        t.Start();  
        int tr = await t;  
        Console.WriteLine(tr);  
    }  
  
    static void Main(string[] args)  
    {  
        Test();  
        Console.WriteLine("Main");  
        Console.ReadKey();  
    }  
}  

 Test函数就用最简单的方法使用了这两个关键字,执行这段代码,首先输出“Main”,而后3秒钟后会输出“1”。

 也可使用:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication11
{
    class Program
    {
        static void Main(string[] args)
        {
            Test();
            Console.WriteLine("Main");
            Console.ReadKey(); 
        }

        private static async void Test()
        {
            var t = Task<int>.Run(() => { Thread.Sleep(3000); return 1; });
            Console.WriteLine(await t);
        }  
    }
}

 

使用async异步编程时,请注意以下事项:

    1. async void 函数只能在UI Event回调中使用。
    2. async void 函数中必定要用try-catch捕获全部异常,不然会很容易致使程序崩溃。
    3. async void 类型的lambda表达式很是隐蔽,而且容易在无心中编写出来,尤为须要注意。
    4. 不要忽视CS4014告警,更不要为了消除CS4014告警而改用 async void 函数。
      确实无需等待的
      async Task 函数用我前面写的扩展函数 IgnorCompletion 消除 这个告警。
    5. 注册 TaskScheduler.UnobservedTaskException事件 ,记录Task中未处理异常信息,方便分析及错误定位。(注意,这个回调里面不能进行耗时操做,具体缘由参看前面的老赵的那篇Blog)
private async void Sync_Button_Click(object sender, RoutedEventArgs e) {
   2:     OutputTextBlock.Text += "開始" + Environment.NewLine;
   3:     // 這裡會等 getFileContentAsync() 執行完畢後, 再執行貼上結束字串那一行
   4:     // 因為 Compiler 會再 await 這行下斷點
   5:     OutputTextBlock.Text += await getFileContentAsync();
   6:     OutputTextBlock.Text += "結束" + Environment.NewLine;
   7: }
   8:  
   9: private async Task<string> getFileContentAsync() {
  10:     StorageFolder folder = KnownFolders.DocumentsLibrary;
  11:     StorageFile file = await folder.GetFileAsync(TESTED_FILE_NAME);
  12:     var result = await FileIO.ReadTextAsync(file) + Environment.NewLine;
  13:     return result;
  14: }
相关文章
相关标签/搜索