Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do you have to await async methods?

Lets say you have a service API call. The callee is somewhat performance critical, so in order not to hold up the API call any longer than necessary, there's an SaveAsync() method that is used. I can't await it, however, because that would hold up the API call just as long (or perhaps even longer) than the non-async version.

The reason I'm asking is this: If you don't await the call, is there a chance the Task object returned gets garbage collected? And if so, would that interrupt the running task?

like image 907
Alex Avatar asked Sep 25 '15 15:09

Alex


People also ask

Should you always await async methods?

If a method is declared async, make sure there is an await! If your code does not have an await in its body, the compiler will generate a warning but the state machine will be created nevertheless, adding unnecessary overhead for an operation that will actually never yield.

Is await mandatory in async function?

An async function without an await expression will run synchronously. The await expression causes async function execution to pause until a Promise is settled (that is, fulfilled or rejected), and to resume execution of the async function after fulfillment.

What happens if you dont await an async method?

The call to the async method starts an asynchronous task. However, because no Await operator is applied, the program continues without waiting for the task to complete. In most cases, that behavior isn't expected.

Can you call an async method without await?

@PeterRitchie You can have a method that is functionally asynchronous, doesn't use the await keyword, and doesn't use the async keyword, but there is no point whatsoever in using the async keyword without also using await in the definition of that method.


2 Answers

The reason I'm asking is this: If you don't await the call, is there a chance the Task object returned gets garbage collected?

Generally, no, that shouldn't happen. The underlying TaskScheduler which queues the task, usually keeps a reference to it for the desired life-time until it completes. You can see that in the documentation of TaskScheduler.QueueTask:

A typical implementation would store the task in an internal data structure, which would be serviced by threads that would execute those tasks at some time in the future.

Your real problem is going to be with the ASP.NET SynchronizationContext, which keeps track of any on-going asynchronous operation at runtime. If your controller action finishes prior to the async operation, you're going to get an exception.

If you want to have "fire and forget" operations in ASP.NET, you should make sure to register them with the ASP.NET runtime, either via HostingEnvironment.QueueBackgroundWorkItem or BackgroundTaskManager

like image 89
Yuval Itzchakov Avatar answered Nov 03 '22 02:11

Yuval Itzchakov


No, it won't interrupt the running task, but you won't observe the exceptions from the task either, which is not exactly good. You can (at least partially) avoid that by wrapping all running code in a try ... catch and log the exception.

Also, if you're inside asp.net, then your whole application could be stopped or recycled, and in this case your task will be interrupted. This is harder to avoid - you can register for AppPool shutdown notification, or use something like Hangfire.

like image 44
Serg Rogovtsev Avatar answered Nov 03 '22 01:11

Serg Rogovtsev