1. 程式人生 > >c# async和await 用法(阻塞與不阻塞)

c# async和await 用法(阻塞與不阻塞)

修正 tar 廣告 ons 定位 ask 問題 ole rendering

void PagePaint()
{
    Console.WriteLine("Paint Start");
    Paint();
    Console.WriteLine("Paint End");
}

void Paint()
{
    Rendering("Header");
    Rendering(RequestBody());
    Rendering("Footer");
}

string RequestBody()
{
    Thread.Sleep(1000);
    return "Body";
}

假設有這麽個頁面布局的方法,依次對頭部、主體和底部進行渲染,頭部和底部是固定的內容,而主體需要額外請求。

這裏用Sleep模擬網絡延時,Rendering方法其實也就是對Console.WriteLine的簡單封裝而已。。。
PagePaint運行過後,結果是這樣的:

Paint Start
Header
Body
Footer
Paint End

挺正常的結果,但是Header渲染完以後頁面就阻塞了,這個時候用戶沒法對Header進行操作。
於是就進行這樣的修正:

async void Paint()
{
    Rendering("Header");
    Rendering(await RequestBody());
    Rendering("Footer
"); } async Task<string> RequestBody() { return await Task.Run(() => { Thread.Sleep(1000); return "Body"; }); }

運行結果變成了這樣:

Paint Start
Header
Paint End
Body
Footer

這樣就能在Header出現之後不阻塞主線程了。

不過呢,Footer一直都得等到Body渲染完成後才能被渲染,這個邏輯現在看來還沒問題,因為底部要相對於主體進行布局。

然而我這時候又想給頁面加一個廣告,而且是fixed定位的那種,管啥頭部主體想蓋住就蓋住,你們在哪它不管。
比如這樣寫:

async void Paint()
{
    Rendering(await RequestAds());
    Rendering("Header");
    Rendering(await RequestBody());
    Rendering("Footer");
}

出現了很嚴重的問題,頭部都得等廣告加載好了才能渲染,這樣顯然是不對的。
所以應該改成這樣:

async void Paint()
{
    PaintAds();
    Rendering("Header");
    Rendering(await RequestBody());
    Rendering("Footer");
}

async void PaintAds()
{
    string ads = await Task.Run(() =>
    {
        Thread.Sleep(1000);
        return "Ads";
    });
    Rendering(ads);
}

這樣的運行結果就算令人滿意了:

Paint Start
Header
Paint End
Ads
Body
Footer

c# async和await 用法(阻塞與不阻塞)