什么是異步編程


什么是異步編程呢?舉個簡單的例子:

using System.Net.Http;
using System.Threading.Tasks;
using static System.Console;

namespace Core
{
    class Async
    {
        static void Main()
        {
            Start();
            End();
        }

        static void Wait()=>WriteLine("waiting...");
        static void End()=>WriteLine("end...");
        static int Start()
        {
            WriteLine("start...");
            HttpClient client = new HttpClient();
            Waiting();
            var result = client.GetStringAsync("https://www.visualstudio.com/");
            string str = result.Result;
            return str.Length;
        }
    }
}

上面這段代碼中,Main方法中的代碼是按照自上而下的順序執行的。網絡狀況不佳時,Start()方法是比較耗時(注意,這里在Start方法中調用了異步方法GetStringAsync,但該方法在此處是以同步方式執行的,具體原因下文會進行說明),在Start()方法執行完畢之前,整個程序處於阻塞狀態。而異步編程可以很好的解決這個問題,一句簡單的話來概括異步編程就是,程序無須按照代碼順序自上而下的執行

async/await

C#5.0新增了async和await關鍵字,使用這兩個關鍵字可以大大簡化異步編程

使用 async 關鍵字可將方法、lambda 表達式匿名方法標記為異步,即,方法中應該包含一個或多個await表達式,但async關鍵字本身不會創建異步操作。

public async Task Asy()
{
  //do something...
}
這里需要注意一點,若使用async關鍵字標記的方法中沒有使用await關鍵字(編譯器會給出警告但不報錯),那么該方法將會以同步方式執行。

定義異步方法的幾點要求

定義一個異步方法應滿足以下幾點:

  • 使用async關鍵字來修飾方法
  • 在異步方法中使用await關鍵字(不使用編譯器會給出警告但不報錯),否則異步方法會以同步方式執行
  • 盡量不使用void作為返回類型,若希望異步方法返回void類型,請使用Task
  • 異步方法名稱以Async結尾
  • 異步方法中不能聲明使用ref或out關鍵字修飾的變量

下面定義一個異步方法StartAsync()

static async Task<int> StartAsync()
{
    HttpClient client = new HttpClient();
    var str = await client.GetStringAsync("https://www.visualstudio.com/");
    return str.Length;
}

 

異步方法的返回類型

  • Task<T>
    如果在調用匿名方法時使用了await關鍵字,且匿名方法的返回類型是Task<T>,那么我們得到的返回類型是T。若未使用await關鍵字,則返回類型是Task。未使用await,調用GetStringAsync方法時result是Task類型。

  

從上圖我們可以看到調用GetStringAsync方法時未使用await關鍵字,result是Task類型,我們可以通過GetType()方法來獲取result的詳細類型信息:

從上圖可以看到result的類型全名是System.Threading.Tasks.Task

 


 

從上圖我們可以看到使用await關鍵字時,result是string類型,而匿名方法GetStringAsync的返回類型是Task<string>

  • Task
    如果在調用匿名方法時使用了await關鍵字,且匿名方法的返回類型是Task,那么我們得到的返回類型是void。若為使用await關鍵字,則得到的返回類型是Task。

  • void
    不建議使用void作為異步方法的返回值。
    因為使用Task或Task<TResult>任務作為返回值,其屬性攜帶有關其狀態和歷史記錄的信息,如任務是否完成、異步方法是否導致異常或已取消以及最終結果是什么。而await運算符可訪問這些屬性。

異步方法執行流程


異步程序執行流程

 

 


免責聲明!

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



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