c# async和await 用法(阻塞與不阻塞)
阿新 • • 發佈:2018-07-30
read 底部 lba art paint 方法 完成後 圖片 網絡
看示例吧:
1 void PagePaint() 2 { 3 Console.WriteLine("Paint Start"); 4 Paint(); 5 Console.WriteLine("Paint End"); 6 } 7 8 void Paint() 9 { 10 Rendering("Header"); 11 Rendering(RequestBody()); 12 Rendering("Footer"); 13 } 14 15 string RequestBody() 16 { 17 Thread.Sleep(1000); 18 return "Body"; 19 }
假設有這麽個頁面布局的方法,依次對頭部、主體和底部進行渲染,頭部和底部是固定的內容,而主體需要額外請求。
這裏用Sleep模擬網絡延時,Rendering方法其實也就是對Console.WriteLine的簡單封裝而已。。。
PagePaint運行過後,結果是這樣的:
Paint Start Header Body Footer Paint End
挺正常的結果,但是Header渲染完以後頁面就阻塞了,這個時候用戶沒法對Header進行操作。
於是就進行這樣的修正:
1 async void Paint() 2 { 3 Rendering("Header"); 4 Rendering(await RequestBody()); 5 Rendering("Footer"); 6 } 7 8 async Task<string> RequestBody() 9 { 10 return await Task.Run(() => 11 { 12 Thread.Sleep(1000); 13 return "Body"; 14 }); 15 }
運行結果變成了這樣:
Paint Start Header Paint End Body Footer
這樣就能在Header出現之後不阻塞主線程了。
不過呢,Footer一直都得等到Body渲染完成後才能被渲染,這個邏輯現在看來還沒問題,因為底部要相對於主體進行布局。
然而我這時候又想給頁面加一個廣告,而且是fixed定位的那種,管啥頭部主體想蓋住就蓋住,你們在哪它不管。
比如這樣寫:
1 async void Paint() 2 { 3 Rendering(await RequestAds()); 4 Rendering("Header"); 5 Rendering(await RequestBody()); 6 Rendering("Footer"); 7 }
出現了很嚴重的問題,頭部都得等廣告加載好了才能渲染,這樣顯然是不對的。
所以應該改成這樣:
1 async void Paint() 2 { 3 PaintAds(); 4 Rendering("Header"); 5 Rendering(await RequestBody()); 6 Rendering("Footer"); 7 } 8 9 async void PaintAds() 10 { 11 string ads = await Task.Run(() => 12 { 13 Thread.Sleep(1000); 14 return "Ads"; 15 }); 16 Rendering(ads); 17 }
這樣的運行結果就算令人滿意了:
Paint Start Header Paint End Ads Body Footer
c# async和await 用法(阻塞與不阻塞)