Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 453 Vote(s) - 3.57 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to wait for async method to complete?

#1
I'm writing a WinForms application that transfers data to a USB HID class device. My application uses the excellent Generic HID library v6.0 which can be found [here][1]. In a nutshell, when I need to write data to the 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 isn't able to respond right away so I need to wait for this call to return before I continue. As it currently exists, RequestToGetInputReport() is declared like this:


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'm not very familiar with the workings of the new async/await technologies in .NET 4.5. I did a little reading earlier about the await keyword and that gave me the impression that the call to GetInputReportViaInterruptTransfer() inside of RequestToGetInputReport() would wait (and maybe it does?) but it doesn't seem like the call to RequestToGetInputReport() itself is waiting because I seem to be re-entering the while loop almost immediately?

Can anyone clarify the behavior that I'm seeing?


[1]:

[To see links please register here]

Reply

#2
The following snippet shows a way to ensure the awaited method completes before returning to the caller. HOWEVER, I wouldn't say it's 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.")
Reply

#3
Avoid `async void`. Have your methods return [`Task`][1] instead of `void`. Then you can [`await`][2] 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();
}


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#4
Actually I found this more helpful for functions that return IAsyncAction.

var task = asyncFunction();
while (task.Status == AsyncStatus.Completed) ;
Reply

#5
The most important thing to know about `async` and `await` is that `await` _doesn't_ wait for the associated call to complete. What `await` does is to return the result of the operation immediately and synchronously _if the operation has already completed_ or, if it hasn't, to schedule a continuation to execute the remainder of the `async` method and then to return control to the caller. When the asynchronous operation completes, the scheduled completion will then execute.

The answer to the specific question in your question's title is to block on an `async` method's return value (which should be of type `Task` or `Task<T>`) by calling an appropriate `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 asynchronous method `GetFooAsync`. However, this pattern is to be avoided for the most part since it will block a whole thread pool thread for the duration of the asynchronous operation. This an inefficient use of the various asynchronous mechanisms exposed by APIs that go to great efforts to provide them.

The answer at

[To see links please register here]

has several, more detailed, explanations of these keywords.

Meanwhile, @Stephen Cleary's guidance about `async void` holds. Other nice explanations for why can be found at

[To see links please register here]

and

[To see links please register here]

Reply

#6
Best Solution to wait AsynMethod till complete the task is

var result = Task.Run(async() => await yourAsyncMethod()).Result;
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through