C#中異步編程Async和Await 的用法

C#5.0(.NET Framework 4.5)提供Async和Await關鍵字來實現異步編程。

關於使用這兩個關鍵字官方說明如下:

  • 方法簽名包含一個 Async 或 async 修飾符

  • 按照約定,異步方法的名稱以“Async”後綴結尾。

  • 返回類型爲下列類型之一:

    • 如果你的方法有操作數爲 TResult 類型的返回語句,則爲 Task<TResult>。

    • 如果你的方法沒有返回語句或具有沒有操作數的返回語句,則爲 Task。

    • 如果你編寫的是異步事件處理程序,則爲 Void(Visual Basic 中爲 Sub)。

    • 有關詳細信息,請參見本主題後面的“返回類型和參數”(點擊此處看官網完整說明)。

    • 方法通常包含至少一個 await 表達式,該表達式標記一個點,在該點上,直到等待的異步操作完成方法才能繼續。 同時,將方法掛起,並且控件返回到方法的調用方。 本主題的下一節將解釋懸掛點發生的情況。

這裏附上官方MSDN的鏈接:

 

//實例

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

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("--------------------------------------------------------------------");
            Console.WriteLine("主線程開始執行,時間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            Console.WriteLine("--------------------------------------------------------------------");            /*
            * 主線程調用ShowInfoAsync異步方法
            * 使用async和await關鍵字
            */
            ShowInfoAsync();
            Console.WriteLine(string.Empty);            /*同步操作*/
            for (int i = 0; i < 3; i++)
            {
                Thread.Sleep(1000);
                Console.WriteLine(string.Format("主線程同步:第{0}次循環,時間:{1}", i + 1, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
            }

            Console.WriteLine("--------------------------------------------------------------------");
            Console.WriteLine("主線程執行結束,時間:" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            Console.WriteLine("--------------------------------------------------------------------");
            Console.ReadKey();
        }
        /// <summary>
        /// 異步顯示輸出信息
        /// </summary>
        static async void ShowInfoAsync()
        {

            //聲明要調用的異步方法,獲取異步任務操作類 Task
            //Task<string> getTask = GetDataAsync();

            Console.WriteLine(string.Empty);
            Console.WriteLine(string.Format("開始執行異步獲取數據方法,時間:{0}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));            /*
             * 異步獲取數據並顯示
             * 這裏使用 await 關鍵詞啓用並等待異步返回結果
             * 在聲明await關鍵詞的地方線程就會在此等待返回結果
             * 只有返回結果纔會繼續執行下面步驟
             */
            string strShowString = await GetDataAsync();

            Console.WriteLine("***************************************************************");
            Console.WriteLine(string.Format("異步獲取數據執行結束,獲取數據值:{0},時間:{1}", strShowString, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
            Console.WriteLine("***************************************************************");
            Console.WriteLine(string.Empty);
        }
        /// <summary>
        /// 異步獲取返回的數據
        /// </summary>
        /// <returns></returns>
        static async Task<string> GetDataAsync()
        {            //這裏也可以使用Task.Run
            return await Task.Run(() =>
            {
                string strReturn = string.Empty;
                for (int i = 0; i < 5; i++)
                {
                    Thread.Sleep(1000);
                    Console.WriteLine(string.Format("異步:第{0}次循環,時間:{1}", i + 1, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")));
                    strReturn += i.ToString();
                }
                return strReturn;
            });
        }
    }
}

//例子中如果是同步編程的話一共循環8次需要3+5=8秒,而使用異步編程的話只需要5秒,節省了3秒

項目應用

private async void button1_Click(object sender, EventArgs e)
{
    var t = Task.Run(() => {
        Thread.Sleep(5000);
        return "webapi";
    });
    textBox1.Text = await t;
}

 

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