Given your example
public async Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
Logger.LogInfo("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
Logger.LogInfo is called synchronously
- The
async keyword gives the method PushCallAsync the capability to await, but it never awaits anything
If you intend to make the method run asynchronously - as the name PushCallAsync implies -, you have to find an alternative to synchronously calling LogInfo.
If a LogInfoAsync method exists, trying to evade using await is ill-advised. Await is important because:
- It captures and throws exceptions that may occur on the task execution - which would otherwise be lost / unhandled
- It ensures execution order by waiting for the result
If you specifically want a fire-and-forget behavior, where you do not depend on execution order (e.g. in this case you don't care about the order of the log messages), you call LogInfoAsync() without awaiting the result.
Since you don't use any await you do not mark the method async. What makes it asynchronous is not the async keyword but it calling other methods asynchronously.
public Task PushCallAsync(CallNotificationInfo callNotificationInfo)
{
// Fire and forget - we do not care about the result, failure, or order of this log message
_ = Logger.LogInfoAsync("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
Task.CompletedTask;
}
or non-async
public void PushCall(CallNotificationInfo callNotificationInfo)
{
// Fire and forget - we do not care about the result, failure, or order of this log message
_ = Logger.LogInfoAsync("Pushing new call {0} with {1} id".Fill(callNotificationInfo.CallerId,
}
Note that the method name Push implies it is in order. So I would name it differently if you don't care about order. Otherwise, as Push implies, using await would be correct to ensure order.
Task.Rundirectly.async/awaitisn't really a multithreading mechanism, in fact I think the runtime executes things on as few threads as possible. It's mostly about the compiler automatically transform your code into continuation-passing style so you only wait for results (or completion) of a background operation when absolutely necessary. When you don't need to wait (orawait) for the results of your call, this is not the language feature you're looking for.asyncinteracts with threads is a bit more complex, and the default behavior can be easily overridden.asyncis not a multithreading mechanism, nor does it always run on a single thread. I have a blog post that summarizes howasyncschedules its continuations.