Wait for a void async method
Best practice is to mark function async void
only if it is fire and forget method, if you want to await on, you should mark it as async Task
.
In case if you still want to await, then wrap it like so await Task.Run(() => blah())
Flutter: Wait for async void method
Change the return type to Future<void>
.
Future<void> save(Folder folder) async {
.....
}
Then you can do await save(...);
or save().then(...);
How to wait for async void to complete?
Return Task
(not Task<T>
) instead of void
. Note, the non-generic form of Task
does not need to wrap a value. It's just for signalling completion or errors, not results. In the case of async
methods, this is equivalent to a synchronous void
return type. It means you can wait for your method to complete.
Do I have to wait for void async functions?
Question - by the time f() returns, can one be sure that ProcessResponse is done?
Absolutely not.
f
is declared async
, it returns a promise and hands control back to g
as soon as it goes to sleep while it awaits another promise.
That is before ProcessResponse
is even called.
What if g is not declared as async - will that make a difference?
No
This can be demonstrated:
const obj = { ProcessResponse: () => console.log("Process Response")};
function NetworkRequest() { return new Promise( res => setTimeout(() => res(obj), 1000) );}
async function f(x){ console.log("f, before await"); var f = await NetworkRequest(x); console.log("f, after await"); f.ProcessResponse(); console.log("f, after Process Response");}
async function g(){ console.log("g, before f"); f(x); console.log("g, after f");}
const x = "global";g();
How to wait for a async void method to complete its task?
await().untilAsserted(() -> someVoidMethod());
how to wait for await in async method to finish the all the executions?
If you need LoadSystemDetails
to wait for GetAllFields
, there are 2 problems here:
- you are calling async method from a synchronous context
GetAllFields
is async void, which means fire and forget. You will never be able to wait for it to finish.
Solution:
First, NEVER use async void
if you need to wait for the result or end. Use async Task
instead
Second, either convert LoadSystemDetails
to async method also, then await the GetAllFields (that should return Task
), or use GetAllFields(clientId).Wait()
take a look at this article for more information on async/await: https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
async/await - when to return a Task vs void?
Normally, you would want to return a
Task
. The main exception should be when you need to have avoid
return type (for events). If there's no reason to disallow having the callerawait
your task, why disallow it?async
methods that returnvoid
are special in another aspect: they represent top-level async operations, and have additional rules that come into play when your task returns an exception. The easiest way is to show the difference is with an example:
static async void f()
{
await h();
}
static async Task g()
{
await h();
}
static async Task h()
{
throw new NotImplementedException();
}
private void button1_Click(object sender, EventArgs e)
{
f();
}
private void button2_Click(object sender, EventArgs e)
{
g();
}
private void button3_Click(object sender, EventArgs e)
{
GC.Collect();
}
f
's exception is always "observed". An exception that leaves a top-level asynchronous method is simply treated like any other unhandled exception. g
's exception is never observed. When the garbage collector comes to clean up the task, it sees that the task resulted in an exception, and nobody handled the exception. When that happens, the TaskScheduler.UnobservedTaskException
handler runs. You should never let this happen. To use your example,
public static async void AsyncMethod2(int num)
{
await Task.Factory.StartNew(() => Thread.Sleep(num));
}
Yes, use async
and await
here, they make sure your method still works correctly if an exception is thrown.
For more information see: https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming
Getting a Cannot await void, on a method that I have want to await on
For methods that are inherently synchronous, you need to wrap them in your own Task
so you can await it. In your case, I would just use Task.Run
:
await Task.Run(() =>
{
rptViewer.LocalReport.DataSources.Add(new ReportDataSource("MyData", CoreUtils.ToDataTable(itemsSource)));
});
There are other ways to generate a task, but this one is probably the easiest. If this updates a UI component, it will likely throw an exception because those operations must occur on the UI thread. In this case, try to get the UI related piece away from the long-running part and only wrap the long part in the Task
.
Using async await inside void method
You can still make a void
method async:
protected async void CannotChangeSignature()
{
...
}
Valid return types for an async method are:
void
Task
Task<T>
However, if you want to make it actually block, then you're basically fighting against the platform - the whole point is to avoid blocking.
You say you can't change the signature - but if you're relying on this blocking then you've got to change the way you approach coding.
Ideally you should change the signature to Task<bool>
:
protected async Task<bool> CannotChangeSignature()
{
...
try
{
await ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
return true;
}
catch(FileNotFoundException)
{
return false;
}
}
EDIT: If you really need a blocking one, you'll just have to call AsTask().Wait()
, catch the AggregateException
and check whether it contains a FileNotFoundException
. It really is pretty horrible though... can you not design around this so that it doesn't need to be blocking? For example, start checking for the file, and show an error (or whatever) if and when you find it doesn't exist.
Related Topics
How to Simulate a Mouse Click at a Certain Position on the Screen
Get the Sourcecontrol of a Dropdownmenu
C# Marking Class Property as Dirty
ASP.NET Identity Change Password
Ms Chart Rectangular Annotation Width in Percent and Not Pixel
How to Make Ef-Core Use a Guid Instead of String for Its Id/Primary Key
Where Is Httpcontent.Readasasync
How to Get the List of All Printers in Computer
Order of Execution with Multiple Filters in Web API
Openfiledialog Can't Load CSV Files But Can Load Xls/Xlsx Excel Files
Ensure That Httpconfiguration.Ensureinitialized()
Change Pinned Taskbar Icon (Windows 7)
Micro Optimization of a 4-Bucket Histogram of a Large Array or List
How to Use Acrylic Accent in Windows 10 Creators Update
How to Write a Unit Test to Determine Whether an Object Can Be Garbage Collected