C# async await

目錄

一.寫法

二.用法


這裏詳細記錄一下 async 和 await 的用法和注意點,當然前提是對 Task 比較瞭解了,因爲 async 和 await 核心還是在 Task ,下面以實例來說明:

一.寫法

先介紹一下寫法,剛接觸這兩個關鍵字的時候,看別人寫的代碼總有些看不懂,後來發現原來是熟手們都喜歡簡寫,導致新手看不懂,如:

private static async Task<string> TestFunction()
{
	return await Task.Run(()=>"Test1");
}

完整的寫法應是:

private static async Task<string> TestFunction()
{
    Task<string> task = new Task<string>(() =>
    {
        return "Test1";
    });
    task.Start();
    var result = await task;
    return result;
}

從完整的寫法可以看出,await 等待的是 Task, 返回的是 Task Result 對應的具體類型值。

 

二.用法

下面以一些示例來說明具體用法和注意點:

1.示例,探究:只要是 async 方法裏的操作,都不阻礙當前線程?

static void Main(string[] args)
{
    Console.WriteLine("Test Start");
    TestFunction();
    Console.WriteLine("Test End");
    Console.Read();
}

private static async Task<string> TestFunction()
{
    return await Task.Run(() =>
    {
        Thread.Sleep(2000);

        string result = "Test1";
        Console.WriteLine(result);
        return result;
    });
}

結果:

把 TestFunction 方法改成:

private static async Task<string> TestFunction()
{
    Thread.Sleep(2000);

    return await Task.Run(() =>
    {
        string result = "Test1";
        Console.WriteLine(result);
        return result;
    });
}

此時結果:

由此看出,只有在 Task 裏的延遲,纔不會阻礙當前UI線程,而不是隻要放在 async 方法裏就可以。

2.示例,探究:在 async 方法中使用多個 await

private static async Task<string> TestFunction()
{
	var task1Result = await TestFunction1();
	var task2Result = await TestFunction2();
	var result = $"{task1Result}+{task2Result}";

	return await TestFunction3(result);
}

private static async Task<string> TestFunction1()
{
	return await Task.Run(() =>
	{
		Thread.Sleep(2000);
		return "TestFunction1";
	});
}

private static async Task<string> TestFunction2()
{
	return await Task.Run(() =>
	{
		Thread.Sleep(3000);
		return "TestFunction2";
	});
}

private static async Task<string> TestFunction3(string str)
{
	return await Task.Run(() =>
	{
		Thread.Sleep(1000);
		Console.WriteLine(str);
		return str;
	});
}

結果:

但是一般不這麼用,因爲得到最後的結果共花了6秒:

更改 TestFunction 代碼:

private static async Task<string> TestFunction()
{
    Task<string> task1 = TestFunction1();
    Task<string> task2 = TestFunction2();
    var result = await Task.WhenAll(task1, task2);

    string output = string.Join("+", result);

    return await TestFunction3(output);
}

這樣得到最後結果只花 4 秒。

總結,

1.並不是說遇到 async 方法就會進入多線程處理,從而不阻礙當前線程,異步處理還是在 await 的 Task 中;

2.await 方法會阻礙後面的代碼執行,但是僅僅在帶有 async 關鍵字的方法中生效,並不會阻塞調用 async 方法的線程,這纔是核心。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章