我试着理解为什么更好地使用' Async'方法比使用简单的旧同步方式。
我不明白有一个小问题。
以同步方式:
FileStream.Read(...)
的线程。 以A同步的方式:
TheadAsync01
')调用方法FileStream.ReadAsync(...)
。 现在,当IRP发出信号表示此IO请求已完成时发生了什么?
(主题TheadAsync01
现在正在做其他事情,并且无法继续使用' FileStream.ReadAsync
'现在返回。
其他线程会继续使用ReadAsync
的返回值继续下一个操作吗?
我在这里不明白?
答案 0 :(得分:5)
困扰你的原因是这个错误的假设:
线程TheadAsync01现在正在做其他事情并且无法继续 使用' FileStream.ReadAsync'现在回来。
在典型的应用程序中,I / O是迄今为止最耗时的任务。
正确使用TPL时,线程不会被耗时的操作阻塞。相反,所有耗时的工作(换句话说,任何I / O)都是通过await
委派的。因此,当您的IRP发出信号时,线程将无法工作,或者很快就会免费。
如果有一些繁重的计算(非常耗时的不 I / O),您需要相应地进行规划,例如在专用线程上运行它。
答案 1 :(得分:2)
函数ReadAsync立即返回一个值,即一个Task对象。在某个地方你应该用返回值做一些事情。规范的方法是使用await:
await FileStream.ReadAsync(...)
这将确保在ReadAsync完成其工作之前,调用站点不会继续操作。如果你想在此期间做某事,你可以稍后等待任务对象,或者你可以手动处理任务对象。
如果您只是调用ReadAsync,忽略返回的任务对象,不执行任何操作,那么您的阅读大多是昂贵的无操作。
答案 2 :(得分:1)
当*** Async方法返回任务或任务时,您可以使用它来跟踪异步操作的运行。通过在任务上调用.Wait(),可以使调用与调用代码同步。或者,从.Net 4.5开始,您可以等待任务。
e.g:
private async void DoFileRead(...)
{
var result = await fileStream.ReadAsync(...);
// Do follow on tasks
}
在这种情况下,任何后续代码都将被编译器包含在一个延续中,并在异步调用完成时执行。使用async关键字的一个要求是使用async关键字标记调用方法(参见上面的示例)。