如果那个异步方法不是个假异步方法,那么的确异步方法的吞吐量会更高,资源占用更少,会释放线程资源……
正确的理解异步的的方式是通过回调函数理解。
真正的异步方法是通过通知延续来实现等待效果的,而同步方法是阻塞线程来实现等待效果的。
简单说就是同步方法线程被阻塞直到操作完成,异步方法线程被释放,接到完成通知后再复原堆栈从中断处执行。
第二个问题
其实这是微软没说清楚的一个问题,Task最开始很单纯就是用来做任务并行库(TPL)的,Task标识一个代码片段的执行过程,所以Task有状态:等待激活,正在运行,完成,取消和失败。
任务并行库认为所有要并行执行的东西都可以视为一个个小小的任务(Task),任务被任务调度器(TaskScheduler)调度,任务也是调度的最小单位,不能调度执行半个任务,一个任务要么执行成功,要么执行失败或者被终止取消。如果需要执行的任务太多,线程池不够线程分配,那么任务就要排队,也就是等待激活状态。
转眼到了.NET Framework 4.5,天才的Anders搞出了async/await,然后他没有另外发明一个Promise类型,而是直接用现成的Task类型来作为Promise用。所以就让Task有了双重身份,async的Promise和任务并行库的任务。
也正因为此,事实上任务并行库并不能做异步调用的调度,因为任务并行库是将代码块封装成Task去调度,和异步调用完全不搭界。要做异步调用的调度、串联或者并发控制,可以用System.Threading.Tasks.Dataflow