c# - Task.Run 以增加 IO 绑定(bind)操作的并行性?

标签 c# async-await task-parallel-library

我对 Task.Run 和我在互联网上读到的所有内容感到有点困惑。所以这是我的情况:我有一些处理传入套接字数据的函数:

public async Task Handle(Client client)
{
    while (true)
    {
        var data = await client.ReadAsync();
        await this.ProcessData(client, data);
    }
}

但这有一个缺点,我只能在处理完最后一个请求后才能读取下一个请求。所以这是一个修改后的版本:

public async Task Handle(Client client)
{
    while (true)
    {
        var data = await client.ReadAsync();
        Task.Run(async () => {
            await this.ProcessData(client, data);
        });            
    }
}

这是一个简化版本。对于更高级的,我当然会限制并行请求的最大数量。

无论如何,这个 ProcessData 主要是 IO 绑定(bind)的(对 dbs 进行一些调用,非常轻的处理并将数据发送回 client),但我一直在阅读我应该使用的内容Task.Run 具有 CPU 绑定(bind)函数。

Task.Run 是否适合我的情况?如果不是,还有什么替代方案?

最佳答案

从概念上讲,这是 Task.Run 的一个很好的用法。它与 ASP.NET 分派(dispatch)请求的方式非常相似:(异步)读取请求,然后分派(dispatch)(同步或异步)工作到线程池。

在实践中,您需要确保正确处理 ProcessData 的结果。特别是,您需要观察异常。按照目前的代码,ProcessData 的任何异常都将被吞噬,因为未观察到从 Task.Run 返回的任务。

IMO,处理每条消息错误的最简洁方法是拥有自己的try/catch,如下所示:

public async Task Handle(Client client)
{
  while (true)
  {
    var data = await client.ReadAsync();
    Task.Run(async () => {
      try { await this.ProcessData(client, data); }
      catch (Exception ex) {
        // TODO: handle
      }
    });            
  }
}

其中 //TODO: handle 是适合您的应用程序的错误处理代码。例如,您可能会在套接字上发送错误响应,或者只是记录并忽略。

关于c# - Task.Run 以增加 IO 绑定(bind)操作的并行性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48426265/

相关文章:

c# - 身份 Entity Framework 库 - 更新数据库 [MySQL]

c# - 如何使用 XmlSerializer 在大型文档中插入节点

c# - ASP.NET MVC 中身份验证的 OutputCache 困境

vue.js - "Default Apollo Queries"VS "AsyncData"(Nuxt.js)

c# - 如何在 TPL 中停止播放并返回正确的值?

c# - Action<T> 与标准返回

c# - Contains 如何返回 false 但 GetHashCode() 返回相同的数字,而 Equals 返回 true?

javascript - 从嵌套的 async/await 函数中捕获错误

c# - Parallel.ForEach 和异步等待

c++ - 在多个时间戳执行函数