Wat*_* v2 25 .net c# asynchronous async-await
考虑一段代码,例如:
public async Task<Bitmap> DownloadDataAndRenderImageAsync(
CancellationToken cancellationToken)
{
var imageData = await DownloadImageDataAsync(cancellationToken);
return await RenderAsync(imageData, cancellationToken);
}
Run Code Online (Sandbox Code Playgroud)
此方法中的第一步是I/O绑定工作,其中第二步是计算.
当我们依赖编译器为这个异步操作生成正确的基于任务的代码时,编译器会做什么?
具体来说,它是否知道第一个是I/O绑定所以它必须使用TaskCompletionSource<T>该类,以便线程和任务之间没有亲和力,而对于第二个,它可以使用任何方法,如Run或StartNew或者Start在线程池线程上安排任务?
Jon*_*eet 40
在您给出的示例中,编译器将仅TaskCompletionSource<T>(间接)使用整个异步操作(DownloadDataAndRenderImageAsync).由两个方法决定它们将如何返回相关任务.
也许DownloadImageDataAsync它本身就是一种async委托更多异步I/O的方法.也许是RenderAsync电话Task.Run.这些都是实现细节,编译器不关心在所有编译时DownloadDataAndRenderImageAsync.
Eri*_*ert 34
当我们依赖编译器为这个异步操作生成正确的基于任务的代码时,编译器会做什么?
在示例中,您给编译器知道DownloadImageDataAsync和RenderAsync是返回awaitables的方法.等待是可以(1)查询完成的对象,以及(2)在完成之前签署的继续.编译器生成的代码检测返回的等待是否已完成,如果不是,则在等待的完成时注册方法的其余部分.
具体来说,它是否知道第一个是I/O绑定
不.它知道它返回了一些等待的东西.
所以它必须使用TaskCompletionSource类,以便线程和任务之间没有亲和力
如果您关心完成逻辑的细节,那么您有责任确保await发生的上下文是正确的上下文.如果您不在乎,您将获得适当的默认上下文.
而对于第二个,它可以使用任何方法,如Run或StartNew或Start来在线程池线程上安排任务?
编译器没有做任何这样的事情.编译器生成的代码检查返回的等待是否完成,如果没有,则报告等待完成.等待的工作方式是被调用者的责任,而不是编译器的责任!
usr*_*usr 16
编译器和运行时都不知道.事实上,整个术语"IO界限"含糊不清.是否有任何操作系统调用IO?!正在睡觉或计时IO?!
如果你不得不提出这个问题,你可能会对任务产生一些误解,因为通常没有必要知道这一点.
也许认为等待开始任务是常见的错误?它等待现有任务完成.DownloadImageDataAsync并RenderAsync决定如何以及何时完成该任务.因此他们决定是使用CPU还是执行IO.
当DownloadImageDataAsync和RenderAsync手你一个任务,你不知道里面有什么,你不需要知道.
| 归档时间: |
|
| 查看次数: |
2558 次 |
| 最近记录: |