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