国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

批判“await使用中的阻塞和并發(fā)”——對(duì)asyc/await這對(duì)基友的誤會(huì)和更正

2019-11-17 03:21:17
字體:
供稿:網(wǎng)友

批判“await使用中的阻塞和并發(fā)”——對(duì)asyc/await這對(duì)基友的誤會(huì)和更正

2014-02-16 16:03 by 樓上那個(gè)蜀黍, ... 閱讀, ... 評(píng)論, 收藏, 編輯

  寫第一篇《await使用中的阻塞和并發(fā)》的時(shí)候還自信滿滿,覺得寫的真不錯(cuò),結(jié)果漏洞百出……

  更正第二篇《await使用中的阻塞和并發(fā)(二)》的時(shí)候覺得這回不會(huì)再錯(cuò)了……

  結(jié)果我正在寫第三篇,而且連篇名都不敢延用了……

  首先完善第二篇對(duì)Foreach(Action<T>)的拆解,用很厲害的小兄弟geelaw的話說就是“是用另一個(gè)方法返回λ表達(dá)式創(chuàng)建的委托,并未把λ表達(dá)式換成方法。”慚愧啊,在小兄弟的指點(diǎn)下,修改代碼如下,在Foreach(Action)這個(gè)話題上算是圓滿了:

        public void AwaitFuncTaskListNoLambda()        {            var funcList = new List<Func<Task>>()            {                Delay3000Async,                Delay2000Async,                Delay1000Async            };             //funcList.ForEach(async _ => await _());            //funcList.ForEach(AwaitAction());            //foreach (var func in funcList)            //{            //    AwaitAction()(func);            //}             Action<Func<Task>> L = this.Xxx;            foreach (var func in funcList)            {                L(func);            }        }                async void Xxx(Func<Task> ft)        {            await ft();        }        public Action<Func<Task>> AwaitAction()        {            return async _ => await _();        }    

  接下來的文字是本篇的重點(diǎn),來自redjackwang菊苣的指點(diǎn),他指出了我第二篇中仍存在的誤區(qū)和錯(cuò)誤。下面讓我們來領(lǐng)略一下大牛的風(fēng)采。首先從上篇我給出的結(jié)論入手:

  1. async用于異步,可以優(yōu)美的替代Thread、BackgroundWorker和Task.Run等寫法。
  2. await用于等待。一定是在你主動(dòng)希望阻塞并等待返回結(jié)果時(shí)才使用。
  3. 在async方法里,Task在創(chuàng)建時(shí)就開始運(yùn)行了。

  第一點(diǎn)需要指出這里的替代僅僅是寫法的變化,async方法內(nèi)部具體實(shí)現(xiàn)可能仍使用Thread等多線程技術(shù)來實(shí)現(xiàn)。這里需要明確async/await僅是一個(gè)異步的寫法,而Thread/BackgroundWorker和Task是多線程。

  關(guān)于第二點(diǎn),有兩位菊苣分別提出異議。redjackwang的原話是“await并不會(huì)阻塞任何線程。await只是把當(dāng)前方法狀態(tài)保存并立即返回,不管是主線程還是后臺(tái)線程都不會(huì)阻塞,而是在完成時(shí)call一個(gè)回調(diào)。”胖胖的韋恩卑鄙是這么說的:“說await是主動(dòng)阻塞問題很大。那叫做響應(yīng)式休眠?

  至于第三點(diǎn),那是MSDN坑我,redjackwang大人竟然從MSDN上找到了更詳細(xì)的答案來證明我給出的鏈接是錯(cuò)誤的。在此一定要共享出來給各位,不要被我上篇錯(cuò)誤的結(jié)論誤導(dǎo)了,正確的表述如下:

Tasks created byits publicconstructors are referred to as “cold” tasks, in that they begin their life cycle in the non-scheduled TaskStatus.Created state, and it’s not until Start is called on these instances that they PRogress to being scheduled. All other tasks begin their life cycle in a “hot” state, meaning that their asynchronous execution has already been initiatedand theirTaskStatusis an enumerationvalueotherthan Created.

All tasks returned from TAP methods must be “hot.” If a TAP method internally uses a Task’s constructor to instantiate the task to be returned, the TAP method must call Start on the Task object prior to returning it.Consumers of a TAP methodmaysafelyassume that the returned task is “hot,” andshould not attempt to callStart on any Task returned from a TAP method.Calling Start on a “hot” taskwill result in anInvalidOperationException(this check is handled automatically by the Task class).

  為此redjackwang還給出了證明的例子,在這個(gè)例子中,如果注釋掉start方法,Task是不會(huì)自動(dòng)運(yùn)行的。結(jié)論是Task如果是通過構(gòu)造函數(shù)創(chuàng)建的,狀態(tài)是cold的,不會(huì)自動(dòng)運(yùn)行,而前一篇都是通過返回Task的方法創(chuàng)建出來的,狀態(tài)是hot,所以自動(dòng)運(yùn)行了,和在不在async方法中沒有關(guān)系。

private async void Button_Click(object sender, RoutedEventArgs e){    var v = await Foo();    this.Title = v.ToString();} private async Task<long> Foo(){    var t = new Task<long>(() =>    {        long z = 0;        for (int i = 0; i < 100000; i++)        {            z += i;        }        return z;    });    //t.Start();    return await t;}

  本篇應(yīng)不是最終的結(jié)果,后面如有進(jìn)一步的發(fā)現(xiàn)仍會(huì)更新下去,批判的暴風(fēng)雨還在繼續(xù)……


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 泸定县| 年辖:市辖区| 石首市| 雷山县| 辽中县| 扶风县| 定日县| 博白县| 饶平县| 赣榆县| 鹤岗市| 缙云县| 平邑县| 阿拉尔市| 信阳市| 安阳市| 壤塘县| 仁寿县| 怀柔区| 梁河县| 双鸭山市| 武冈市| 太仓市| 同仁县| 海盐县| 白河县| 吉水县| 疏勒县| 凤翔县| 尼勒克县| 玉屏| 保山市| 陇西县| 漠河县| 鸡西市| 湄潭县| 丹凤县| 泽库县| 新营市| 搜索| 嘉荫县|