标签:info ext sha 函数 部分 class 电话 ui线程 for
普通函数
string Func() { string x = X(); string y = Y(); string z = Z(); return x + y + z; }
X(), Y(), Z()内部都Sleep 10s, 则Func()耗时30s
异步函数
async string FuncAsync() { string x = await XAsync(); string y = await YAsync(); string z = await ZAsync(); return x + y + z; }
假设 XAsync(), YAsync(), YAsync()内部都Sleep10s, 则FuncAync()还是耗时多少呢?
整个FuncAsync会被拆成如下部分:
这些部分会被.NET同步上下文SynchronizationContext在同一个线程依次执行,如下:
所以耗时时间还是30s
假设 XAsync(), YAsync(), YAsync()内部都把Sleep10s用Task.Run()都包起来返回
所以FuncAsync总耗时时间还是30s,优点是UI线程不会被卡住, UI线程不是被FuncAsync一个任务占有,其他异步任务也能在UI线程上执行,真正等待的任务都运行在后台线程。
下面这个版本,FuncAsync()执行的时间才是10s
async string FuncAsync() { var taskX = XAsync(); var taskY = YAsync(); var taskZ = ZAsync(); await Task.WhenAll(taskX, taskY, taskZ); return taskX.Result + taskY.Result + taskZ.Result; }
如果在XAsync()里调用Task.Result同步等待会怎样?
XAsync要等待的结果(task.Result),需要同步上下文返回,
虽然后台线程已经同步上下文结果了,但同步上下文此时却还在执行XAsync的过程中.
互相等待,于是产生死锁.
举个形象的例子:
标签:info ext sha 函数 部分 class 电话 ui线程 for
原文地址:http://www.cnblogs.com/mrfangzheng/p/7294459.html