async await example

 

async 跟 await 都會是成對出現,如下例

static async Task GetTaskAsync(string input)
{
    await Task.Delay(0);
    Console.WriteLine(nameof(GetTaskAsync) + " - " + input);
}

而 await 後面會接 Task,以表示等候該任務完成。

 

範例一、

using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Show();
            Console.ReadKey();
        }

        static async void Show()
        {
            // Calls to GetTaskOfTResultAsync  
            Task<string> returnedTaskTResult = GetTaskOfTResultAsync("a");
            string intResult = await returnedTaskTResult;
            Console.WriteLine(intResult);

            // or, in a single statement  
            string intResult2 = await GetTaskOfTResultAsync("b");
            Console.WriteLine(intResult2);

            // Calls to GetTaskAsync  
            Task returnedTask = GetTaskAsync("c");
            await returnedTask;
            // or, in a single statement  
            await GetTaskAsync("d");
        }

        // Signature specifies Task<TResult>  
        static async Task<string> GetTaskOfTResultAsync(string input)
        {
            await Task.Delay(2000);
            // Return statement specifies an integer result.  
            return input + " Task complete -GetTaskOfTResultAsync";
        }

        // Signature specifies Task  
        static async Task GetTaskAsync(string input)
        {
            await Task.Delay(0);
            Console.WriteLine(input + " Task complete " + " -GetTaskAsync");
            // The method has no return statement.    
        }
    }
}

 

範例二、

using System;
using System.Threading.Tasks;
using System.Threading;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            // 帶有純委派方法的 Task 物件,需要呼叫 Start 方法才會執行
            Action<object> action = (object obj) =>
            {
                Console.WriteLine("obj = {0}, Task.CurrentId = {1}, Thread.CurrentThread.ManagedThreadId = {2}",
                obj, Task.CurrentId,
                Thread.CurrentThread.ManagedThreadId);
            };
            // .NET framework 4.0 開始提供 Task 類別。
            Task alpha = new Task(action, "alpha");
            alpha.Start();

            //---------------------------------------------------------------
            // 由關鍵字 async 搭配回傳型別為 Task 的委派方法,
            // 其委派方法在指定給 Task 型別的物件時就會自動執行
            Task returnedTask1 = GetTaskAsync("a");
            Task returnedTask2 = GetTaskAsync("b");
            Task returnedTask3 = GetTaskAsync("c");

            //---------------------------------------------------------------
            // 此語法可執行,但會有警告
            // GetTaskAsync("d");

            //---------------------------------------------------------------
            // 此為錯誤語法,當使用 await 關鍵字時,他的上一層,
            // 也就是 static void Main(string[] args),
            // 還要加上對應的 async 關鍵字,成為 static async Task Main(),
            // 但這在 C#7.1 以上才有支援
            // await GetTaskAsync("e");

            //---------------------------------------------------------------
            Task<string> returnedTask4 = GetTaskOfTResultAsync("f");
            string result = returnedTask4.Result;
            Console.WriteLine("returnedTask4 contect is (" + result + ")");

            Console.ReadKey();
        }

        // Signature specifies Task<TResult>  
        static async Task<string> GetTaskOfTResultAsync(string input)
        {
            await Task.Delay(2000);
            Console.WriteLine(input + " Task complete " + " -GetTaskAsync");
            // Return statement specifies an integer result.  
            return input + " Task complete -GetTaskOfTResultAsync";
        }

        // Signature specifies Task  
        static async Task GetTaskAsync(string input)
        {
            await Task.Delay(1000);
            Console.WriteLine(input + " Task complete " + " -GetTaskAsync");
            // The method has no return statement.    
        }
    }
}

 

說明:

1、An async method runs synchronously until it reaches its first await expression, at which point the method is suspended until the awaited task is complete.

2、If the method that the async keyword modifies doesn't contain an await expression or statement, the method executes synchronously.

3、A compiler warning alerts you to any async methods that don't contain await statements, but it isn't compiler error.

4、An async method can have the following return types:Task、Task<TResult>、void (which should only be used for event handlers).

5、I/O-Bound 適用執行緒處理,CPU-Bound 適用非同步處理。

 

在同步的 Main 裡面使用非同步方法,用 Wait() 等待結果

using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            GetTaskAsync("TIME UP!!!").Wait();
            Console.WriteLine("End");
        }

        static async Task GetTaskAsync(string input)
        {
            for (int i = 3; i > 0; i--)
            {
                Console.SetCursorPosition(0, 0);
                Console.Write(i);
                await Task.Delay(1000);
            }

            Console.WriteLine(nameof(GetTaskAsync) + " - " + input);
        }
    }
}

 

在同步的 Main 裡面使用非同步方法,用 GetResult() 等待結果

using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            GetTaskAsync("TIME UP!!!").GetAwaiter().GetResult();
            Console.WriteLine("End");
        }

        static async Task GetTaskAsync(string input)
        {
            for (int i = 3; i > 0; i--)
            {
                Console.SetCursorPosition(0, 0);
                Console.Write(i);
                await Task.Delay(1000);
            }

            Console.WriteLine(nameof(GetTaskAsync) + " - " + input);
        }
    }
}

 

參考資料:

async (C# Reference)

await (C# Reference)

Asynchronous programming with async and await (C#)

Asynchronous programming

Async in depth

中文淺顯易懂文章

[C#]TPL與Async Await的觀念還有使用方式

async & await 的前世今生(Updated)

异步编程 In .NET