Wednesday, 28 August 2013

Fire and forget async method

Fire and forget async method

The general answers such as here and here to fire-and-forget questions is
not to use async/await, but to use Task.Run or TaskFactory.StartNew
passing in the synchronous method instead. However, sometimes the method
that I want to fire and forget is async and there is no equivalent sync
method.
for example:
//External library
public async Task DeleteFooAsync();
In my asp.net mvc code I want to call DeleteFooAsync in a fire-and-forget
fashion - I don't want to hold up the response waiting for DeleteFooAsync
to complete. If DeleteFooAsync fails (or throws an exception) for some
reason, there is nothing that the user or the program can do about it so I
just want to log an error.
Now, I know that any exceptions will result in unobserved exceptions, so
the simplest case I can think of is:
//In my code
DeleteFooAsync()
//In my App_Start
TaskScheduler.UnobservedTaskException += ( sender, e ) =>
{
m_log.Debug( "Unobserved exception! This exception would have been
unobserved: {0}", e.Exception );
e.SetObserved();
};
However, DeleteFooAsync() results in a warning:
Because this call is not awaited, execution of the current method
continues before the call is completed. Consider applying the 'await'
operator to the result of the call.
I could disable the warning, but are there any risks in doing this?
The other option that I can think of is to make my own wrapper such as:
private void async DeleteFooWrapperAsync()
{
try
{
await DeleteFooAsync();
}
catch(Exception exception )
{
m_log.Error("DeleteFooAsync failed: " + exception.ToString());
}
}
and then call that with TaskFactory.StartNew (probably wrapping in an
async action). However this seems like a lot of wrapper code each time I
want to call an async method in a fire-and-forget fashion.
My question is, what it the correct way to do a fire-and-forget async method?

No comments:

Post a Comment