C# 非同步程式設計Task(三) async、await

天马3798發表於2024-04-20

一、async和await兩個修飾符

C#5.0的時候引入了async和await兩個修飾符,成為非同步程式設計的核心關鍵字。
async 是修飾符,表明方法含有非同步操作,但並不是說整個方法是非同步的。async修飾的方法會先同步執行到第一處await的地方而後開始非同步。
await可以理解為一非同步特有的“return”。即返回一個正在執行的非同步過程。並且等待該非同步過程結束後再繼續向await的下一句執行。

private static async void MainAsync()
{
    Console.WriteLine("Application Start");
    await AsyncTask1();//編譯報錯,“無法等待void”
    Console.WriteLine("Application End");
}

private static async void AsyncTask1()
{
    Console.WriteLine("AsyncVoid1");
    Thread.Sleep(1000);
    Console.WriteLine("AsyncVoid1: befor await");
    await Task.Run(() =>
    {
        Console.WriteLine("AsyncVoid1: Task Runing");
        Thread.Sleep(2000);
    });
    Console.WriteLine("AsyncVoid1: after await");
}
static void Main(string[] args)
{
     //控制檯Main入口不能加async
      MainAsync();
}
//方法內有await時,方法必須被async修飾。
private static async void MainAsync()
{
    Console.WriteLine("Application Start");
    await AsyncTask1();
    Console.WriteLine("Application End");
}

執行結果:

Application Start
AsyncVoid1
AsyncVoid1: befor await
AsyncVoid1: Task Runing
AsyncVoid1: after await
Application End

二、非同步返回型別

async是方法的修飾,其對應的方法的返回值有

void
Task
Task<T>
任何具有可訪問的 GetAwaiter 方法的型別(GetAwaiter 方法返回的物件必須實現 ystem.Runtime.CompilerServices.ICriticalNotifyCompletion 介面)。
IAsyncEnumerable(對於返回非同步流的非同步方法)。
常用的是前三個。暫且置整理前三者的區別與不同。


三、async Task
返回Task型別的。個人概括的說,就是“執行操作但不返回任何值的非同步方法”。即await 等待的一個無返回值的Task。

private static async Task<int> AsyncFuncReturn1()
{
    await Task.Run(() => 
    { 
        Thread.Sleep(500); 
    });            
    return 1;
}
private static Task<int> AsyncFuncReturn2()
{
    return Task<int>.Run(() => 
    { 
        Thread.Sleep(500); 
        return 1; 
    });
}

四、await 和 Task.Wait()/Task.Result

await 和Task.Wait()的作用都有等待任務結束的功能,不同的是,就想前面說的,await還有一層“return”的意思,或者說更像“yield”。即讓await所在方法的被呼叫者可以繼續下一步操作。(這裡只是說“可以”,即對外產生這樣的能力,而如果await所在方法返回的值是void型別,呼叫者就不能強制同步了)

更多:

C# 非同步程式設計Task整理(一)

C# 非同步程式設計Task整理(二)異常捕捉

C# 最簡單的使程式單程序執行的方法

相關文章