asp.net core 中async/await 使用

asp.net core 中async/await 使用

async/await是用来进行异步调用的形式,内部其实还是采用线程池进行管理。
我们从两方面来看其运行机制,运行流程和运行线程。

单独的await

        public async Task<string> call()
        {
            Debug.WriteLine("----------->1");
            int s = await foo();
            Debug.WriteLine("----------->2");
            return "1";
        }
        public async Task<int> foo()
        {
            Debug.WriteLine("----------->3");
            await Task.Delay(500);
            Debug.WriteLine("----------->4");
            return 1;
        }

运行结果:

----------->1
----------->3
----------->4
----------->2

这个很好理解,先主线程运行,然后运行子线程foo()方法,线程等待foo方法运行完毕之后再继续往下运行。

我们从线程的角度来看一下这里面的线程切换。
Talk is cheap, show me the code

        public async Task<string> Get()
        {
            var info = string.Format("----------->1:{0}", Thread.CurrentThread.ManagedThreadId);
            var infoTask = await TaskCaller();
            var infoTaskFinished = string.Format("----------->2:{0}", Thread.CurrentThread.ManagedThreadId);
            return string.Format("{0},{1},{2}", info, infoTask, infoTaskFinished);
        }

        private async Task<string> TaskCaller()
        {
            await Task.Delay(500);
            return string.Format("----------->3:{0}", Thread.CurrentThread.ManagedThreadId);
        }

结果是

----------->1:1
----------->3:4
----------->2:4

冒号后面的是线程编号,一开始主线程为1,然后进入到子线程4,跳出来之后居然在线程4中执行!很神奇,异步线程接管了接下来的活!

有人就要说了,这个await很同步获取result一样啊,看不出有什么异步的优势在里面,客官莫急,接下来慢慢看。

分开的await

        public async Task<string> call()
        {
            Debug.WriteLine("----------->1");
            Task<int> infoTask = foo();
            Debug.WriteLine("----------->2");
            int s = await infoTask;
            Debug.WriteLine("----------->3");
            return "1";
        }
        public async Task<int> foo()
        {
            Debug.WriteLine("----------->4");
            await Task.Delay(500);
            Debug.WriteLine("----------->5");
            return 1;
        }

定义异步方法foo,然后在call方法中调用,与第一个例子不一样的是这个例子foo()不立马使用await,而是运行一段之后再使用await,结果输出如下:

----------->1
----------->4
----------->2
----------->5
----------->3

看看这个神奇的线程输出吧。
Talk is cheap, show me the code

        public async Task<string> Get()
        {
            var info = string.Format("----------->1:{0}", Thread.CurrentThread.ManagedThreadId);
            Task<string> task = TaskCaller();
            var infoTaskRunning = string.Format("----------->2:{0}", Thread.CurrentThread.ManagedThreadId);
            var infoTask = await task;
            var infoTaskFinished = string.Format("----------->3:{0}", Thread.CurrentThread.ManagedThreadId);
            return string.Format("{0},{1},{2},{3}", info, infoTask,infoTaskRunning, infoTaskFinished);
        }

        private async Task<string> TaskCaller()
        {
            await Task.Delay(500);
            return string.Format("----------->4:{0}", Thread.CurrentThread.ManagedThreadId);
        }

猜猜结果是什么。

----------->1:1
----------->4:4
----------->2:1
----------->3:4

一开始运行在主线程,后来跳到async方法中执行在线程4中,在没有使用await时,主线程并没有停下来,还是按照自己的路往下走,直到async使用了await方法,下面的代码也是交给了子线程。
至于为什么交给了子线程处理,有一篇文章说是await前后的代码被分成块,将await的task交给线程池,线程池执行完毕之后进行moveNext方法,继续执行await之后的代码。
有兴趣的可以看看这篇文章
async和await刨根问底

当有多个async方法在主程序中被调用

执行的流程就不说了,大家都清楚,主要来看看执行的线程
Talk is cheap, show me the code

        public async Task<string> Get()
        {
            var info = string.Format("----------->1:{0}", Thread.CurrentThread.ManagedThreadId);
            Task<string> task1 = TaskCaller1();
            Task<string> task2 = TaskCaller2();
            var infoTaskRunning = string.Format("----------->2:{0}", Thread.CurrentThread.ManagedThreadId);
            var infoTask1 = await task1;
            var infoTaskFinished1 = string.Format("----------->3:{0}", Thread.CurrentThread.ManagedThreadId);

            var infoTask2 = await task2;
   
            var infoTaskFinished2 = string.Format("----------->4:{0}", Thread.CurrentThread.ManagedThreadId);

            return string.Format("{0},{1},{2},{3},{4},{5}", info, infoTask1, infoTask2,infoTaskRunning, infoTaskFinished1, infoTaskFinished1);
        }

        private async Task<string> TaskCaller1()
        {
            await Task.Delay(500);
            return string.Format("----------->5:{0}", Thread.CurrentThread.ManagedThreadId);
        }

       private async Task<string> TaskCaller2()
        {
            await Task.Delay(500);
            return string.Format("----------->6:{0}", Thread.CurrentThread.ManagedThreadId);
        }

结果如下:

----------->1:4
----------->5:3
----------->6:12
----------->2:4
----------->3:3
----------->4:3

有没有有个数字很奇怪,对,就是最后的3,前面讲过async会接过线程来自己操作下面的代码,第一个异步方法确实是这样做了,使得第一个await async之后在线程3上面操作,
而第二个await之后却还是在线程3上面操作,这不免有些让人疑惑,还是建议去看上面推荐的async和await刨根问底

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 196,099评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,473评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,229评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,570评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,427评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,335评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,737评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,392评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,693评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,730评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,512评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,349评论 3 314
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,750评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,017评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,290评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,706评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,904评论 2 335

推荐阅读更多精彩内容