【问题标题】:Why is Task.Run required here?为什么这里需要 Task.Run?
【发布时间】:2021-08-27 15:28:13
【问题描述】:

我有一个来自 Web 应用程序的 API 调用,它使用 Dapper 来查询一些结果并将它们返回给用户。但是,为什么这是异步工作的

IEnumerable<Task<Policy>> getPolicyTasks = from policy in policyList select GetPolicyDetailAsync(policy);

IEnumerable<Task<Policy>> tasks = policyList.Select(policy => Task.Run(() => GetPolicyDetailAsync(policy)));

var policyResults = await Task<Policy>.WhenAll(tasks);

但这不是吗?

List<Task<Policy>> getPolicyTasks = new List<Task<Policy>>();

foreach (var policy in policyList)
      getPolicyTasks.Add(GetPolicyDetailAsync(policy));

var policyResults = await Task.WhenAll(getPolicyTasks);

policies = policyResults.ToList();

GetPolicyAsync 是一个简单的 Dapper SQL 调用,如下所示:

policies = await db.QueryAsync<Policy, Address, Policy>(sql,
   (policy, address) =>
   {
       policy.Address = address;
       return policy;
   },
   param: new { input = policy },
   splitOn: "Address1");

return policy;

似乎我所有的 API 调用服务都需要使用 Task.Run() 来异步运行。为什么当方法是异步和等待时会出现这种情况?

【问题讨论】:

  • 您使用的是哪个SqlClientSystem.Data.SqlClientMicrosoft.Data.SqlClient?以及为什么要在循环中执行此操作,而您只需执行一个查询即可一次获取所有PolicyDetail
  • 实际上是 IBM Net5.IBM.Data.Db2 (Informix)。我知道在这个特定区域一次完成所有操作可能更有意义,但这只是一个一般示例。我有一些长时间运行的数据库操作需要异步运行。
  • 提供程序可能不是为正确使用async 而构建的
  • 谢谢@Charlieface,你是对的。事实证明 IBM DB2 并不完全支持异步 - 感谢您的帮助。
  • 正如我所说,您可能希望找到一种方法在一个查询中执行此操作。 DB2 是否支持表参数?

标签: c# .net async-await


【解决方案1】:

事实证明,IBM DB2 提供程序并不完全支持异步操作,因此我需要为此使用 Task.Run。说得通。感谢@Charlieface 为我指明了正确的方向。

【讨论】:

  • 很高兴知道不只是Oracle 驱动程序有这个问题!
  • I need to use Task.Run for it - 不要在 ASP.NET 上为此使用 Task.Run。让它同步运行。使用Task.Run 是您的代码释放线程的一种方式......通过使用另一个线程来代替。它只会导致上下文切换,根本没有任何好处。
  • 感谢它同步运行的折射方法,但还有其他一些实例是有意义的,因此这些实例将保留(IE 从多个方法创建对象)现在只需要执行时间一小部分时间
猜你喜欢
  • 2012-06-03
  • 1970-01-01
  • 2010-12-15
  • 2019-01-16
  • 2021-10-22
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多