简体   繁体   English

调用异步方法时真正发生了什么?

[英]What really happens when call async method?

I try to understand why is better using the 'Async' method than using simple old synchronous way. 我试图理解为什么使用“异步”方法比使用简单的旧同步方法更好。

There is small issue that I don't understand. 有一个我不明白的小问题。

On the synchronous way: 在同步方式上:

  1. I have some thread that call method FileStream.Read(...) . 我有一些线程调用FileStream.Read(...)方法。
  2. Because calling this method is synchronous so the calling thread will wait until the IRP (I/O request packet) will signal that this Io request is finish. 因为调用此方法是同步的,所以调用线程将等待,直到IRP(I / O请求数据包)将发出信号通知此Io请求已完成。 Until the IRP will return ==> this thread will suspend ( sleep ). 在IRP返回==>之前,该线程将挂起(sleep)。

On the A-synchronous way: 在A同步方式下:

  1. I have some thread (Task .. lets call this thread ' TheadAsync01 ') that calls method FileStream.ReadAsync(...) . 我有一些线程(Task ..让我们将此线程称为' TheadAsync01 '),该线程调用方法FileStream.ReadAsync(...)
  2. Because calling this method is A-Synchronous so the calling thread will not wait until the IRP (I/O request packet) will signal that this IO request is finish; 因为调用此方法是A同步的,所以调用线程将不会等待,直到IRP(I / O请求数据包)将发出该IO请求完成的信号。 and this calling thread will continue to his next action. 并且此调用线程将继续执行他的下一个动作。

Now, When the IRP will signal that this IO request is finish what happened? 现在,当IRP发出信号通知此IO请求完成时,发生了什么?

(The thread TheadAsync01 is now doing something else and can't continue the work with what the ' FileStream.ReadAsync ' return now.) (线程TheadAsync01现在正在做别的事情,无法继续使用什么“工作FileStream.ReadAsync现在的回归。)

Is other thread will continue the continue the next action with the return value of the ReadAsync ? 是否其他线程将继续使用ReadAsync的返回值继续下一个操作?

What I don't understand here? 我在这里不明白什么?

The reason it bothers you is this mistaken assumption: 困扰您的原因是这个错误的假设:

The thread TheadAsync01 is now doing something else and can't continue the work with what the 'FileStream.ReadAsync' return now. 线程TheadAsync01现在正在做其他事情,无法继续执行'FileStream.ReadAsync'现在返回的内容。

In a typical application I/O is by far the most time-consuming task. 在典型的应用程序中,I / O是迄今为止最耗时的任务。

When TPL is used correctly, threads are not blocked by time-consuming operations. 正确使用TPL时,耗时的操作不会阻塞线程。 Instead, everything time-consuming (in other words, any I/O) is delegated via await . 相反,所有耗时的操作(换句话说,任何I / O)都通过await委托。 So when your IRP signals, the thread will either be free from work, or will be free very soon. 因此,当您的IRP发出信号时,该线程将不再工作,或者很快将被释放。

If there's some heavy calculation (something time-consuming which is not I/O), you need to plan accordingly, for example run it on a dedicated thread. 如果有大量的计算( 不是 I / O的耗时的事情),则需要进行相应的计划,例如在专用线程上运行它。

The function ReadAsync immediately returns a value, namely a Task object. ReadAsync函数立即返回一个值,即Task对象。 Somewhere you should do something with the return value. 在某个地方,您应该对返回值进行处理。 The canonical way is to use await: 规范的方法是使用await:

await FileStream.ReadAsync(...)

This will ensure that the calling site will not continue with operation until ReadAsync has completed its job. 这将确保在ReadAsync完成其工作之前,呼叫站点不会继续运行。 If you want to do something in the meantime you could await the task object later or you can manually deal with the task object. 如果要在此期间做某事,则可以稍后等待任务对象,也可以手动处理任务对象。

If you just call ReadAsync, ignoring the returned task object, doing nothing with it, then your reading is mostly an expensive no-op. 如果您只是调用ReadAsync,而忽略返回的任务对象,而对其不执行任何操作,则您的阅读大部分都是昂贵的无操作操作。

When a ***Async method returns a Task or Task you use this to track the running of the asynchronous operation. 当*** Async方法返回一个Task或Task时,您可以使用它来跟踪异步操作的运行。 You can make the call behave synchronously with respect to the calling code by calling .Wait() on the task. 您可以通过在任务上调用.Wait()使调用相对于调用代码同步进行。 Alternatively, as of .Net 4.5 you can await the task. 或者,从.Net 4.5开始,您可以等待任务。

eg: 例如:

private async void DoFileRead(...)
{
    var result = await fileStream.ReadAsync(...);
    // Do follow on tasks
}

In this scenario any follow on code would be wrapped in a continuation by the compiler and executed when the async call completed. 在这种情况下,任何后续代码都将由编译器包装在一个连续文件中,并在异步调用完成时执行。 One requirement of using the async keyword is to mark the calling method with the async keyword (see the example above). 使用async关键字的一项要求是用async关键字标记调用方法(请参见上面的示例)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM