C#異步編程(async and await)及異步方法同步調用

一、什麼是異步?

異步操做一般用於執行完成時間可能較長的任務,如打開大文件、鏈接遠程計算機或查詢數據庫=異步操做在主應用程序線程之外的線程中執行。應用程序調用方法異步執行某個操做時,應用程序可在異步方法執行其任務時繼續執行。數據庫

二、同步與異步的區別

同步(Synchronous):在執行某個操做時,應用程序必須等待該操做執行完成後才能繼續執行。編程

異步(Asynchronous):在執行某個操做時,應用程序可在異步操做執行時繼續執行。實質:異步操做,啓動了新的線程,主線程與方法線程並行執行。網絡

三、異步和多線程的區別

咱們已經知道, 異步和多線程並非一個同等關係,異步是最終目的,多線程只是咱們實現異步的一種手段。異步是當一個調用請求發送給被調用者,而調用者不用等待其結果的返回而能夠作其它的事情。實現異步能夠採用多線程技術或則交給另外的進程來處理。多線程

簡單的說就是:異步線程是由線程池負責管理,而多線程,咱們能夠本身控制,固然在多線程中咱們也可使用線程池。異步

就拿網絡扒蟲而言,若是使用異步模式去實現,它使用線程池進行管理。異步操做執行時,會將操做丟給線程池中的某個工做線程來完成。當開始I/O操做的時候,異步會將工做線程還給線程池,這意味着獲取網頁的工做不會再佔用任何CPU資源了。直到異步完成,即獲取網頁完畢,異步纔會經過回調的方式通知線程池。可見,異步模式藉助於線程池,極大地節約了CPU的資源。async

注:DMA(Direct Memory Access)直接內存存取,顧名思義DMA功能就是讓設備能夠繞過處理器,直接由內存來讀取資料。經過直接內存訪問的數據交換幾乎能夠不損耗CPU的資源。在硬件中,硬盤、網卡、聲卡、顯卡等都有直接內存訪問功能。異步編程模型就是讓咱們充分利用硬件的直接內存訪問功能來釋放CPU的壓力。異步編程

二者的應用場景:spa

  • 計算密集型工做,採用多線程。線程

  • IO密集型工做,採用異步機制。code

C#異步代碼參考(async and await)

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

namespace AsyncAwaitDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("main start..");
            AsyncMethod();
            Thread.Sleep(1000);
            Console.WriteLine("main end..");

            Console.ReadLine();
        }

        static async void AsyncMethod()
        {
            Console.WriteLine("start async");
            var result = await MyMethod();
            Console.WriteLine("end async");
            //return 1;
        }

        static async Task<int> MyMethod()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Async start:" + i.ToString() + "..");
                await Task.Delay(1000); //模擬耗時操做
            }
            return 0;
        }
    }
}

使用Wait()和GetAwaiter().GetResult()方法實現異步方法同步執行

using System;
using System.Threading.Tasks;

namespace AsyncTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Async Test job:");

            Console.WriteLine("main start..");

            Console.WriteLine("MyMethod()異步方法同步執行:");

            MyMethod().Wait();//在main中等待async方法執行完成

            int i = MyMethod().GetAwaiter().GetResult();//用於在main中同步獲取async方法的返回結果

            Console.WriteLine("i:" + i);

            Console.WriteLine("main end..");

            Console.ReadKey(true);
        }

        static async Task<int> MyMethod()
        {
            for (int i = 0; i < 5; i++)
            {
                Console.WriteLine("Async start:" + i.ToString() + "..");
                await Task.Delay(1000); //模擬耗時操做
            }
            return 0;
        }
    }
}
相關文章
相關標籤/搜索