Wait for a void async method - c#

How can I wait for a void async method to finish its job?
for example, I have a function like below:
async void LoadBlahBlah()
{
await blah();
...
}
now I want to make sure that everything has been loaded before continuing somewhere else.

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

If you can change the signature of your function to async Task then you can use the code presented here

The best solution is to use async Task. You should avoid async void for several reasons, one of which is composability.
If the method cannot be made to return Task (e.g., it's an event handler), then you can use SemaphoreSlim to have the method signal when it is about to exit. Consider doing this in a finally block.

You don't really need to do anything manually, await keyword pauses the function execution until blah() returns.
private async void SomeFunction()
{
var x = await LoadBlahBlah(); <- Function is not paused
//rest of the code get's executed even if LoadBlahBlah() is still executing
}
private async Task<T> LoadBlahBlah()
{
await DoStuff(); <- function is paused
await DoMoreStuff();
}
T is type of object blah() returns
You can't really await a void function so LoadBlahBlah() cannot be void

I know this is an old question, but this is still a problem I keep walking into, and yet there is still no clear solution to do this correctly when using async/await in an async void signature method.
However, I noticed that .Wait() is working properly inside the void method.
and since async void and void have the same signature, you might need to do the following.
void LoadBlahBlah()
{
blah().Wait(); //this blocks
}
Confusingly enough async/await does not block on the next code.
async void LoadBlahBlah()
{
await blah(); //this does not block
}
When you decompile your code, my guess is that async void creates an internal Task (just like async Task), but since the signature does not support to return that internal Tasks
this means that internally the async void method will still be able to "await" internally async methods. but externally unable to know when the internal Task is complete.
So my conclusion is that async void is working as intended, and if you need feedback from the internal Task, then you need to use the async Task signature instead.
hopefully my rambling makes sense to anybody also looking for answers.
Edit:
I made some example code and decompiled it to see what is actually going on.
static async void Test()
{
await Task.Delay(5000);
}
static async Task TestAsync()
{
await Task.Delay(5000);
}
Turns into (edit: I know that the body code is not here but in the statemachines, but the statemachines was basically identical, so I didn't bother adding them)
private static void Test()
{
<Test>d__1 stateMachine = new <Test>d__1();
stateMachine.<>t__builder = AsyncVoidMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncVoidMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
}
private static Task TestAsync()
{
<TestAsync>d__2 stateMachine = new <TestAsync>d__2();
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>1__state = -1;
AsyncTaskMethodBuilder <>t__builder = stateMachine.<>t__builder;
<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
neither AsyncVoidMethodBuilder or AsyncTaskMethodBuilder actually have any code in the Start method that would hint of them to block, and would always run asynchronously after they are started.
meaning without the returning Task, there would be no way to check if it is complete.
as expected, it only starts the Task running async, and then it continues in the code.
and the async Task, first it starts the Task, and then it returns it.
so I guess my answer would be to never use async void, if you need to know when the task is done, that is what async Task is for.

do a AutoResetEvent, call the function then wait on AutoResetEvent and then set it inside async void when you know it is done.
You can also wait on a Task that returns from your void async

You can simply change the return type to Task and call await Task.CompletedTask at the end of the function, e.g:
async Task MyFunction() {
await AnotherFunction();
await Task.CompletedTask;
}
I find this simpler than wrapping the whole function body in a call to Task.Run(() => { ... });.

I've read all the solutions of the thread and it's really complicated... The easiest solution is to return something like a bool:
async bool LoadBlahBlah()
{
await blah();
return true;
}
It's not mandatory to store or chekc the return value. You can juste do:
await LoadBlahBlah();
... and you can return false if something goes wrong.

Related

How to call async function with await inside a non async function in c#?

I have an async function call myAsyncfuntion() which look like that
public async Task TakePhotoBasicAndSaveAndDisplayUWP()
{
var photoImplementation = new MediaCaptureImplementation();
photoImplementation.TakePhotoTexture2DAsync();
// Some code here...
await photoImplementation.SavePhotoToPicturesLibraryAsync();
}
Now I would like to call this function from another non async function
so I do like this. Basically I attact a button to TakePhotoBasicAndSaveAndDisplay() and whenever the button got clicked, the function will start the async function inside. But the async function seem not to be called.
public void TakePhotoBasicAndSaveAndDisplay()
{
#if WINDOWS_UWP
var task = Task.Run(async () => await TakePhotoBasicAndSaveAndDisplayUWP());
#endif
}
Could anyone help me ?
I am working with unity
As Marc commented, the only correct answer to "how do I call an asynchronous method from a synchronous method" is "you don't".
But the async function seem not to be called.
It is certainly being called, but it's possible that it may not be working correctly because it is not on the main UI thread. Task.Run is executing it on a thread pool thread. Also, I suspect that the task in var task = Task.Run(async () => await TakePhotoBasicAndSaveAndDisplayUWP()); is never awaited, so any exceptions from TakePhotoBasicAndSaveAndDisplayUWP would be ignored. I.e., exceptions stating that some API must be called from the main UI thread and not a thread pool thread.
I attact a button to TakePhotoBasicAndSaveAndDisplay
If TakePhotoBasicAndSaveAndDisplay is in fact an event handler, then you can use async void:
public async void TakePhotoBasicAndSaveAndDisplay()
{
#if WINDOWS_UWP
await TakePhotoBasicAndSaveAndDisplayUWP();
#endif
}
You do this only if you don't want to await it and "don't care" about the outcome you could make it async void
public async void TakePhotoBasicAndSaveAndDisplayUWP()
{
var photoImplementation = new MediaCaptureImplementation();
photoImplementation.TakePhotoTexture2DAsync();
// Some code here...
await photoImplementation.SavePhotoToPicturesLibraryAsync();
}
than you can call it like
public void TakePhotoBasicAndSaveAndDisplay()
{
#if WINDOWS_UWP
TakePhotoBasicAndSaveAndDisplayUWP();
#endif
}
(see this good tutorial)
You could always call the async method with .Wait() at the end.
myAsyncfuntion.Wait();
It kinda ruins the whole async thing. The method will block synchronously until the task completes.
You could check this response for more details.

Multiple hierarchy of task

I want to call a task which itself call a async method which inturn returna bool value.
I want to do something on the basis of that outcome.
I can get the data on outcome.Result.Result but this does not look good and I wish to have the output in outcome.Result.
I can not figure it out.
Can someone please guide.
private void OnValidated(ValidatedIntergrationEvent evt)
{
var outcome=Task.Factory.StartNew(() => mydata.UpdateValidated());
if (outcome.Result.Result)//This work fine but I think I need something to do so that outcome.Result gives my solution.
{ }
else { }
}
public async Task<bool> UpdateValidated()
{
var result= await Mediator.Send(new ValidatedEvent(this));
return result;
}
public async Task<bool> Handle(ValidatedEvent notification, CancellationToken cancellationToken)
{ //dO WORK
// return Task.FromResult(true);
return true;
}
Since UpdateValidated is already asynchronous, you should just call it directly to execute it. Things like Task.Factory.StartNew or Task.Run offer a way to put synchronous tasks on a new thread so that they can run asynchronously. So you should just call it directly:
private void OnValidated(ValidatedIntergrationEvent evt)
{
var outcome = mydata.UpdateValidated()
// Note: this WILL block, regardless of how you call the async function
var result = outcome.Result;
}
You should try to avoid using .Result though, as this will block synchronous functions until the asynchronous result is ready, and may even cause deadlocks. If the OnValidated is a standard event handler, you could make it asynchronous instead and await your task:
private async void OnValidated(ValidatedIntergrationEvent evt)
{
var result = await mydata.UpdateValidated()
}
But this make this event handler fire and forget which can be dangerous. So you should really try to change your code that you are truly running asynchronously when calling asynchronous code.
Finally, note that you can force the asynchronous task onto a separate thread using Task.Run. This is useful when the asynchronous call also does a lot on the CPU:
var outcome = Task.Run(() => mydata.UpdateValidated());
This looks very similar to your Task.Factory.StartNew() call but returns only a Task<bool> instead of your Task<Task<bool>>. This is because Task.Run has an overload that explicitly allows you to call asynchronous methods which makes Task.Run just pass on the result.

How do I actually write/end an async method in c#?

I get that I need to await thing in an async marked method to make it asynchronous, but I don't get how to actually end the hole it makes.
static async void Example()
{
int t = await getIntAsync();
WriteLine($"computer: {t}");
}
Since getIntAsync is marked async I have to await in that method or I get a warning. But oh no in the method I await on in getIntAsync I have to mark that as aasync, then unless there is an await in there I get a warning. And so on and so forth to infinity it seems. How do I just make it stop?
I've had a few people tell me to put
await Task.Delay(1000);
In my code, but I know the answer can't be as smelly as putting a delay of a second in all my production code.
A couple others said a task method to end it such as
static Task task()
{
//code
}
But unless I mark that async it throws the same warning that got me into this confusion. I know
static Task task()
{
//code
return Task.FromResult(0);
}
Technically it works, but again that seems too much of a code smell to have all over production.
I just don't get it...
EDIT:
Because it was asked for. I know its a very trivial method, but its also just one I'm using for practice.
static async Task<int> getIntAsync()
{
Console.Write("Enter the number: ");
int n = int.Parse(Console.ReadLine());
return n;
}
What is confusing here is that you don't really do something asynchronous. Console.ReadLine() is a synchronous method. Simply typing async or await somewhere does not magically make this asynchronous.
Since this code is only for testing and learning, one way to make it asynchronous is to put it on another thread using Task.Run() (I would not suggest this for many cases in production code):
static Task<int> getIntAsync()
{
Console.Write("Enter the number: ");
return Task.Run(() => int.Parse(Console.ReadLine());
}
There is no async keyword needed here as you are not awaiting something. You just return a Task<int> that is completed when the user has entered a value and that value was parsed.
And your Example() method then works like that:
static async void Example()
{
int t = await getIntAsync();
WriteLine($"computer: {t}");
}
When the await is hit, the control flow is returned to the caller and the rest of this method (the assignment to t and the call to Console.WriteLine()) are scheduled as a continuation that is executed when the Task<int> returned by getIntAsync() has finished.
The following is needed (async keyword is required and so is the await, it's simply best practice):
The Async keyword
The Await keyword
Some process that you want to work independently while the asynchorous process runs.
Typically, you return value comes from your await task (which should fill in the end hole).
Here is example using a StreamReader,
async Task<string> GetStringFromReaderAsync()
{
Streamreader sr = new StreamReader("filename.txt");
Task<string> getStringTask = sr.ReadLineAsync("filepath");
//Allow user to continue with some other work.
DoFileLookup();
string result = await sr.getStringTask();
return result.ToString();
}
More information here: https://msdn.microsoft.com/en-us/library/system.io.streamreader.readlineasync(v=vs.110).aspx
More about Async and Await: https://msdn.microsoft.com/en-us/library/mt674882.aspx
static async Task<int> getIntAsync()
{
Console.Write("Enter the number: ");
int n = int.Parse(Console.ReadLine());
return n;
}
This will run synchronously as there is no await statement And no awaited call to an async method
the general idea is this
public async Task<int> ExecuteAsync() //Method return type is Task<int>
{
// Error: return type is not int. Return type is Task<int>
return db.SaveChangesAsync();
// OK: returns a task handle that you can await on in you code that called ExecuteAsync()
// you thread continues processing in your calling function until you try to read the value from this return statement.
return await db.SaveChangesAsync();
// Ok. Your Thread leaves here and returns when result available.
// no further Processing done in calling function
return db.SaveChangesAsync().Result;
// Ok. This is not required in this case,
// but if you have an async method that has multiple return points,
// and one of them does not depend on an async method, you can wrap
// the output e.g. return await Task.FromResult(0);
return await Task.FromResult(db.SaveChangesAsync().Result);
return 0; //also ok.
}
Adding on to the other answer below.
static async Task<int> GetIntAsync()
{
Console.Write("Enter the number: ");
return await Task.Run(() => int.Parse("1"));
}
This approach makes something that runs synchronously to be wrapped in a task. However you should never do this (unless of course you know what you are doing) as this spawns another thread. One use case where I have used this is for offloading in webservers but otherwise generally its a bad idea. So while you may have begin with the intention of have maximum utilization of a single thread, you have now ended up with two thread working.

What's the difference between awaiting async Task function and calling await inside a void function?

To understand the question please take a look on the await calls and the definition of the function InitSyncContext() of the following example.
Based on that i would like to know how the program will behave on each scenario because i don't fully understand what´s the difference between calling await InitSyncContext(store) and having a await call inside without returning a Task.
For reference i did a research before and i found a similar example here however i think it's different in my case.
*The following code is a simplified example from a real world code just for demonstration purposes.
void Main()
{
Initializer();
}
private async void Initializer()
{
var store = InitLocalStore();
await InitSyncContext(store); // <-- Here, await call
InitFileSync(store);
}
// Here returns Task (without having a return inside. No compile errors)
private async Task InitSyncContext(MobileServiceSQLiteStore store)
{
await Client.SyncContext.InitializeAsync(store);
}
//------------- Second Method -------------
void Main()
{
Initializer();
}
private void Initializer()
{
var store = InitLocalStore();
InitSyncContext(store); // <-- Here without await call
InitFileSync(store);
}
// Here is void but with a async call inside
private async void InitSyncContext(MobileServiceSQLiteStore store)
{
await Client.SyncContext.InitializeAsync(store);
}
What's the difference between awaiting async Task function and calling await inside a void function?
This is perhaps a very big question is best served by reading the fine article Async/Await - Best Practices in Asynchronous Programming by Mr Stephen Cleary.
Some summary points:
Avoid async void - Prefer async Task methods over async void methods
See also
Cleary, S, "Async/Await - Best Practices in Asynchronous Programming", March 2013, Microsoft, https://msdn.microsoft.com/en-us/magazine/jj991977.aspx?f=255&MSPPError=-2147217396, retrieved 14/7/2016
What's the difference between awaiting async Task function and calling await inside a void function?
The whole world! Everything...and then some. Let's take a step back and start with some of the basics.
You should go "async all the way", i.e.; if you're returning an awaitable (Task or Task<T>) these should correctly use the async and await keywords.
There are several things that need to be clarified here. You should not have async void methods, instead you should have async Task - the exception being event handlers (where the delegates are predefined as non-task returning) and the like. Let's examine and pick apart method one (I'm going to ignore the Main entry points):
One
private async void Initializer()
{
var store = InitLocalStore();
await InitSyncContext(store); // <-- Here, await call
...
}
// Here returns Task (without having a return inside. No compile errors)
private async Task InitSyncContext(MobileServiceSQLiteStore store)
{
await Client.SyncContext.InitializeAsync(store);
}
You have an Initializer method that is immediately a code smell as it is async void. This should be async Task and it should have the "Async" suffix. Additionally, you have an InitSyncContext that takes on a store variable and invokes some client initialization work. The code smell here is that you are using async and await. This is not need on simple (single task) workloads like this. Instead you should simply use the return keyword. Example at the very bottom. Let's look at method two:
Two
private void Initializer()
{
var store = InitLocalStore();
InitSyncContext(store); // <-- Here without await call
...
}
// Here is void but with a async call inside
private async void InitSyncContext(MobileServiceSQLiteStore store)
{
await Client.SyncContext.InitializeAsync(store);
}
Things have officially gone from bad to worse! With the misconceptions of the asynchronous nomenclatures, we have assumed that since one method appeared to work "ok" without taking into account the best practices that another method could follow suit. You made the InitSyncContext method async void. The reason methods should not be async void is that they are fire-and-forget. The internal async state machine doesn't have a Task to latch onto and therefore the state is lost. When you remove the caller's await you are saying start this asynchronous operation but you do not care about it's results.
Here is the correct way to implement the desired functionality:
Correct
private async Task InitializerAsync()
{
var store = InitLocalStore();
await InitSyncContextAsync(store);
...
}
// Simply return the task that represents the async operation and let the caller await it
private Task InitSyncContextAsync(MobileServiceSQLiteStore store)
{
return Client.SyncContext.InitializeAsync(store);
}
A note about the Main method from your snippets, if this is part of a console application - the top-level entry point into your async stack would invoke either .Result or .Wait().
Further reading
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx?f=255&MSPPError=-2147217396
In first example compiler generate something like this:
TheadPool.RunTask(()=>InitSyncContext(store)).ContinueWith(()=>InitFileSync(store))
At second — nothing interesting. Because nobody wait the end of the task. All calls will be in main thread exept await Client.SyncContext.InitializeAsync(store);

How to wait for async void to complete?

i need to wait for my async void to finish. It has some await Task.Delay functions in it and I need them to finish before it continues. This void doesn't return anything so I don't see a reason to make it async Task<> and I also shuffle an array inside this void and I declare some variables. So how can I do this ? Is async Task<> the only way ? My void is not expecting any parameters/inputs.
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.
Every async function should return Task instead of void and Task<TResult> instead of TResult. The only exception of this is the event handler.
So if your async function isn't an event handler it should return Task. Once this is done you can await for it...
... ehm, provided that your function is also declared async and returns Task or Task<TResult>, which makes that your clients all must be async.
If you have a sync function and want to call an async function use the following:
var myTask = Task.Run( () => SomeAsyncFunction(...));
// while my task is running you can do other things
// after a while you need the result:
Task.Wait();
// only if SomeAsyncFunction returns Task<TResult>:
TResult result = Task.Result();
Be aware though that this will halt your function until the task is finished. So when possible consider making your function also async. The code would be like:
public async void Button1_Clicked(object Sender, ...)
{
var task = MySlowMultiplier(3, 4);
// while task running you can do other things
// the UI remains responsive
// after a while:
int result = await task;
ProcessResult(result);
}
private async Task<int> MySlowMultiplier(int x, int y)
{
// I'm really slow:
await Task.Delay(TimeSpan.FromSeconds(5));
return x * y;
}
You can use this code.
var result = Task.Run(async() => { return await METHODNAMEHERE(); }).Result;

Categories