How to wait for the completion of the asynchronous method?

I am writing a WinForms application that transfers data to a HID class USB device. My application uses the excellent universal HID library v6.0, which can be found here . In a nutshell, when I need to write data to a device, this is the code that gets called:

private async void RequestToSendOutputReport(List<byte[]> byteArrays) { foreach (byte[] b in byteArrays) { while (condition) { // we'll typically execute this code many times until the condition is no longer met Task t = SendOutputReportViaInterruptTransfer(); await t; } // read some data from device; we need to wait for this to return RequestToGetInputReport(); } } 

When my code drops out of the while loop, I need to read some data from the device. However, the device cannot answer right away, so I need to wait for this call to return before continuing. Since it currently exists, RequestToGetInputReport () is declared as follows:

 private async void RequestToGetInputReport() { // lots of code prior to this int bytesRead = await GetInputReportViaInterruptTransfer(); } 

For what it's worth, the declaration for GetInputReportViaInterruptTransfer () looks like this:

 internal async Task<int> GetInputReportViaInterruptTransfer() 

Unfortunately, I am not very good at working with the new async / await technologies in .NET 4.5. I read a little earlier about the “Wait” keyword, and this gave the impression that the call to GetInputReportViaInterruptTransfer () inside RequestToGetInputReport () would wait (and maybe this is so?), But this does not look like the call to RequestToGetInputReport () itself waits, because that I seem to return immediately to the while loop?

Can someone clarify the behavior that I see?

+127
c # asynchronous async-await
01 Mar. '13 at 3:07
source share
5 answers

Avoid async void . Ask for methods to return Task instead of void . Then you can await them.

Like this:

 private async Task RequestToSendOutputReport(List<byte[]> byteArrays) { foreach (byte[] b in byteArrays) { while (condition) { // we'll typically execute this code many times until the condition is no longer met Task t = SendOutputReportViaInterruptTransfer(); await t; } // read some data from device; we need to wait for this to return await RequestToGetInputReport(); } } private async Task RequestToGetInputReport() { // lots of code prior to this int bytesRead = await GetInputReportViaInterruptTransfer(); } 
+118
Mar 01 '13 at 3:10
source share

The most important thing to know about async and await is that await does not wait for the appropriate call to complete. What await does is to return the result of the operation immediately and synchronously if the operation is already completed, or if it is not, to schedule a continuation, to execute the rest of the async method, and then return control to the caller. When the asynchronous operation completes, the scheduled completion will be performed.

The answer to a specific question in the heading of your question is to block the return value of the async method (which must be of type Task or Task<T> ) by calling the corresponding Wait method:

 public static async Task<Foo> GetFooAsync() { // Start asynchronous operation(s) and return associated task. ... } public static Foo CallGetFooAsyncAndWaitOnResult() { var task = GetFooAsync(); task.Wait(); // Blocks current thread until GetFooAsync task completes // For pedagogical use only: in general, don't do this! var result = task.Result; return result; } 

In this code snippet, CallGetFooAsyncAndWaitOnResult is a synchronous wrapper around the asynchronous GetFooAsync method. However, this pattern should be avoided for the most part, as it will block the entire thread of the thread pool for the duration of the asynchronous operation. This is an inefficient use of the various asynchronous mechanisms provided by the APIs, which make great efforts to provide them.

The answer to “waiting” does not wait for the call to end has a few more detailed explanations for these keywords.

Meanwhile, @Stephen Cleary's async void guide holds. Other interesting explanations can be found at http://www.tonicodes.net/blog/why-you-should-almost-never-write-void-asynchronous-methods/ and https://jaylee.org/archive/. 2012/07/08 / with sharp Async-tips-and-tricks-part-2-asynchronous void.html

+206
Mar 01 '13 at 5:53 on
source share

Best solution to wait for AsynMethod to complete a task

 var result = Task.Run(async() => { return await yourAsyncMethod(); }).Result; 
+60
Jun 16 '17 at 0:14
source share

Actually, I found this more useful for functions that return IAsyncAction.

  var task = asyncFunction(); while (task.Status == AsyncStatus.Completed) ; 
-four
Feb 10 '19 at 21:14
source share

The following snippet shows how to provide the expected method before returning to the caller. HOWEVER, I would not say that this is a good practice. Please edit my answer with explanations if you think otherwise.

 public async Task AnAsyncMethodThatCompletes() { await SomeAsyncMethod(); DoSomeMoreStuff(); await Task.Factory.StartNew(() => { }); // <-- This line here, at the end } await AnAsyncMethodThatCompletes(); Console.WriteLine("AnAsyncMethodThatCompletes() completed.") 
-5
Mar 08 '16 at 21:45
source share



All Articles