我有一本书.net核心API,它有一个构建聚合对象以返回的控制器.

[HttpGet]
public IActionResult myControllerAction()
{      
    var data1 = new sometype1();
    var data2 = new sometype2();
    var data3 = new List<sometype3>();

    var t1 = new Task(() => { data1 = service.getdata1(); });
    t1.Start();

    var t2 = new Task(() => { data2 = service.getdata2(); });
    t2.Start();

    var t3 = new Task(() => { data3 = service.getdata2(); });
    t3.Start();

    Task.WaitAll(t1, t2, t3);

    var data = new returnObject
    {
         d1 = data1,
         d2 = data2,
         d2 = data3
    };

    return Ok(data);
}

这很有效,但是我想知道使用任务是否是最好的解决方案?使用async/await会是一个更好的主意和更被接受的方式吗?

例如,控制器是否应该标记为async,并在对服务方法的每次调用上放置一个等待?

推荐答案

这很有效,但是我想知道使用任务是否是最好的解决方案?使用async/await会是一个更好的主意和更被接受的方式吗?

是的,当然可以.在ASP.NET上进行并行处理会在每个请求中消耗多个线程,这会严重影响您的可伸缩性.异步处理在I/O方面要优越得多.

要使用async,首先从最低级别的通话开始,在服务内部的某个地方.它可能在某个时刻进行HTTP调用;将其更改为使用异步HTTP调用(例如HttpClient).然后让async个从那里自然生长.

最终,您将得到异步getdata1Asyncgetdata2Asyncgetdata3Async方法,这些方法可以并发使用:

[HttpGet]
public async Task<IActionResult> myControllerAction()
{
  var t1 = service.getdata1Async();
  var t2 = service.getdata2Async();
  var t3 = service.getdata3Async();
  await Task.WhenAll(t1, t2, t3);

  var data = new returnObject
  {
    d1 = await t1,
    d2 = await t2,
    d3 = await t3
  };

  return Ok(data);
}

使用这种方法,当三个服务调用正在进行时,myControllerAction使用zero个线程,而不是four个.

.net相关问答推荐

MSBuild:CopyToOutputDirectory不会将本机DLL复制到输出

Azure Function应用程序-如何升级.NET运行时

从窗体中移除另一个控件中引用的控件时获取设计时通知

向从 .NET 序列化的对象添加 Xml 属性

为什么解码后的字节数组与原始字节数组不同?

使用 PEM 文件创建 DSA 签名

使用字典作为数据源绑定组合框

C# 是否(或将)包含用于副作用验证的功能?

静态代码块

是否有 TLS 1.2 的 .NET 实现?

清除 .NET 的 StringBuilder 内容的最佳方法

SQLParameter 如何防止 SQL 注入?

自定义属性的构造函数何时运行?

如何在 C# 中将 null 值设置为 int?

为什么有些对象属性是 UnaryExpression 而有些是 MemberExpression?

C# (.NET) 设计缺陷

C# 中的 F# List.map 类似功能?

立即检测客户端与服务器套接字的断开连接

为什么要使用 C# 类 System.Random 而不是 System.Security.Cryptography.RandomNumberGenerator?

.NET 桌面应用程序中的 Settings.settings 与 app.config