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?
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.
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.
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.
@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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With