c# - Web API : an asynchronous operation was still pending 中的异步无效与异步任务

标签 c# asp.net-web-api async-await

我们有如下所示的 Web API Controller :

public class HomeController : ApiController
{
    Logger logger = new Logger();

    [HttpGet, Route("")]
    public IHttpActionResult Index()
    {
        logger.Info("Some info logging");

        return Ok();
    }
}

在内部,我们的记录器使用 HttpClient 将数据POST 到 Azure 事件中心。这意味着记录器有一个内部调用异步方法的同步方法。

失败的实现

当我们的记录器有一个带有 async void 签名的私有(private)方法时:

public class Logger
{
    public void Info(string message)
    {
        LogAsync(message);
    }

    private async void LogAsync(string message)
    {
        await PostAsync(message);
    }
}

我们看到以下错误:

Yellow screen of death

工作实现

如果我们更改记录器以使用像这样的 async Task 签名,它会起作用:

public class Logger
{
    public void Info(string message)
    {
        LogAsync(message);
    }

    private async Task LogAsync(string message)
    {
        await PostAsync(message);
    }
}

问题

在这两种情况下,我们的日志消息都会发送到事件中心。我想知道为什么 async Task 允许 Controller 返回预期结果,而 async void 导致 InvalidOperationException

此外,是否有关于从同步方法调用异步代码的最佳实践?

我在这里发布了一个示例解决方案: https://github.com/kevinkuszyk/async-task-vs-async-void-sample

最佳答案

避免判断这种方法的优点,您实际问题的答案在 this question 的答案中。 .

有多种方法可以在保持该使用模式的同时修复它:

  • 不要在 LogAsync()await
  • 使用 Task.Run(() => LogAsync());

关于c# - Web API : an asynchronous operation was still pending 中的异步无效与异步任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41000686/

相关文章:

c# - 使用 C# 加密并使用 OpenSSL 解密

c# - Dotnet Core API - 获取 Controller 方法的 URL

c# - 在 ASP NET Web API 中捕获用户上次请求时间戳

rust - 为什么递归异步函数需要 Rust 中的“静态参数”?

c# - 使用 EF6 从数据库中选择大量数据异步

c# - 为什么延迟任务无法完全执行或阻塞 UI?

c# - WebBrowser 与网站的兼容性问题

c# - DataGridView 从更新中跳过列

c# - 未调用 WebApi v2 ExceptionHandler

asp.net-mvc - IIS 劫持 CORS Preflight OPTIONS 请求