简体   繁体   中英

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(...) .
  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. Until the IRP will return ==> this thread will suspend ( sleep ).

On the A-synchronous way:

  1. I have some thread (Task .. lets call this thread ' TheadAsync01 ') that calls method 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; and this calling thread will continue to his next action.

Now, When the IRP will signal that this IO request is finish what happened?

(The thread TheadAsync01 is now doing something else and can't continue the work with what the ' FileStream.ReadAsync ' return now.)

Is other thread will continue the continue the next action with the return value of the 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.

In a typical application I/O is by far the most time-consuming task.

When TPL is used correctly, threads are not blocked by time-consuming operations. Instead, everything time-consuming (in other words, any I/O) is delegated via await . So when your IRP signals, the thread will either be free from work, or will be free very soon.

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.

The function ReadAsync immediately returns a value, namely a Task object. Somewhere you should do something with the return value. The canonical way is to use await:

await FileStream.ReadAsync(...)

This will ensure that the calling site will not continue with operation until ReadAsync has completed its job. 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.

When a ***Async method returns a Task or Task you use this to track the running of the asynchronous operation. You can make the call behave synchronously with respect to the calling code by calling .Wait() on the task. Alternatively, as of .Net 4.5 you can await the task.

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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