學習筆記——異步

1.異步同步的定義多線程

同步方法:多個任務一個一個執行,同一時刻系統中只有一個任務在執行併發

異步方法:發起一個調用,並不等着計算結束,而是直接去運行下一行;剛纔的計算,會啓動一個新的線程去執行異步

 

2.異步同步的比較async

2.1. 同步方法卡界面,由於UI線程忙於計算;異步多線程方法不卡界面,主線程閒置,計算任務交給子線程在作;學習

2.2. 同步方法慢,只有一個線程計算;異步多線程方法快,多個線程併發計算;this

       多線程的資源消耗更多,線程並非越多越好(資源有限/管理線程也消耗資源)線程

2.3. 異步多線程是無序的:啓動無序 執行時間不肯定  結束無序,,資源

       因此不要試圖經過啓動順序或者時間等待來控制流程同步

 

3.異步如何控制執行順序文件上傳

3.1.回調

//IasyncResult,可用於監視調用進度

//DoSomethingLong方法名稱(要執行的操做)

 Action<string> act = this.DoSomethingLong;

 IAsyncResult iAsyncResult = null;

 AsyncCallback callback = ar =>

 {

    // Console.WriteLine(object.ReferenceEquals(ar, iAsyncResult));

     Console.WriteLine(ar.AsyncState);

     Console.WriteLine($"這裏是BeginInvoke調用完成以後才執行的。。。{Thread.CurrentThread.ManagedThreadId.ToString("00")}");

 };

 iAsyncResult = act.BeginInvoke("btnAsync_Click", callback, "異步學習");

3.2.等待

//IAsyncResult.IsCompeted肯定異步調用什麼時候完成(輪詢)

Action<string> act = this.DoSomethingLong;

IAsyncResult iAsyncResult = act.BeginInvoke("btnAsync_Click", null, null);

int i = 1;

while (!iAsyncResult.IsCompleted)//1 卡界面,主線程在等待   2 邊等待邊作事兒  3有偏差(時間)

{

    if (i < 10)

    {

        Console.WriteLine($"文件上傳{i++ * 10}%。。。請等待");

    }

    else

    {

        Console.WriteLine("已完成99%。。。立刻結束");

    }

    Thread.Sleep(200);//偏差時間

}

Console.WriteLine("文件上傳成功!!!");

3.3.狀態

//使用 IAsyncResult.AsyncWaitHandle 獲取 WaitHandle,使用它的 WaitOne 方法將執行一直阻塞到發出 //WaitHandle 信號,而後調用

Action<string> act = this.DoSomethingLong;

IAsyncResult iAsyncResult = act.BeginInvoke("btnAsync_Click", null, null);

//異步變同步(狀態)

 iAsyncResult.AsyncWaitHandle.WaitOne();//一直等待任務完成,第一時間進入下一行

iAsyncResult.AsyncWaitHandle.WaitOne(-1);//一直等待任務完成,第一時間進入下一行

//最多等待1000ms,超時控制

iAsyncResult.AsyncWaitHandle.WaitOne(1000);//最多等待1000ms,不然就進入下一行,能夠作一些超時控制

//調用 BeginInvoke 後可隨時調用 EndInvoke 方法;若是異步調用未完成,EndInvoke 將一直阻塞到

//異步調用完成。

act.EndInvoke(iAsyncResult);//等待

 

4.其餘相關知識

任何的異步多線程,都是跟委託相關。委託中的Invoke方法 是同步的。BeginInvoke開始一個異步的請求,調用線程池中一個線程來執行。

4.1.異步獲取返回值

Func<int, string> func = i => i.ToString();

IAsyncResult iAsyncResult = func.BeginInvoke(DateTime.Now.Year, ar =>

 {

     string resultIn = func.EndInvoke(ar);//對於每一個異步操做,只能調用一次 EndInvoke。

     Console.WriteLine($"This is {ar.AsyncState} 的異步調用結果 {resultIn}");

 }, "異步參數");

//string result = func.EndInvoke(iAsyncResult);//獲取返回值

5.小結

異步、同步和多線程的關係,能夠這樣理解下。

咱們把一個應用程序看作一家飯店的運做。單線程&多線程 看作是接待客人的服務員人數

飯店來客人後,一個客人一個服務員去接待(一個請求一個線程去處理),在此期間,服務員是一直陪着客人的。
可是當客人去吃飯的時候是不須要服務員的(好比程序去處理IO文件[系統的硬件進行操做]),此時該服務員閒着不幹活(線程什麼也沒作,等待IO操做完畢)

上面的程序默認就是同步(一直陪着客人)的而異步是在客人吃飯的時候,服務員就不陪着了,而是去接待其餘客人(處理其它請求),等客人吃完飯,再來一個服務員引導客人進行其它操做(線程池中的線程來處理)。

相關文章
相關標籤/搜索