We have Web API controllers that look like this:
public class HomeController : ApiController
{
Logger logger = new Logger();
[HttpGet, Route("")]
public IHttpActionResult Index()
{
logger.Info("Some info logging");
return Ok();
}
}
Internally, our loggers use the HttpClient
to POST
data to an Azure Event Hub. This means that the logger has a synchronous method which internally calls an asynchronous method.
When our logger has a private method with an async void
signature like this:
public class Logger
{
public void Info(string message)
{
LogAsync(message);
}
private async void LogAsync(string message)
{
await PostAsync(message);
}
}
We see the following error:
If we change our logger to use an async Task
signature like this it works:
public class Logger
{
public void Info(string message)
{
LogAsync(message);
}
private async Task LogAsync(string message)
{
await PostAsync(message);
}
}
In both cases our logging messages are sent to the Event Hub. I'd like to know why async Task
allows the controller to return the expected result, and async void
results in an InvalidOperationException
?
Also, is there any best practice regarding calling into asynchronous code from a synchronous method?
I've posted a sample solution here: https://github.com/kevinkuszyk/async-task-vs-async-void-sample
Avoiding judgement on the merits of this approach, the answer to your actual question is in the answer to this question .
There are various ways you could fix it while maintaining that usage pattern:
await
in LogAsync()
Task.Run(() => LogAsync());
If you call an async
method synchronously call it as follows:
async Task MyMethod()
{
...
}
public void WaitOnTask()
{
var resultTask = MyMethod();
resultTask.GetAwaiter().GetResult();
}
async void
should be avoided because there is nothing stopping the method returning immediately and this causes problems when the caller is not expecting the method to return without the asynchronous process completing as is the case in the ASP.NET runtime.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.