加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 将Task.WhenAll用于多个异步和伪异步方法

发布时间:2020-12-16 01:28:11 所属栏目:百科 来源:网络整理
导读:我的一位同事重构了我们的控制器方法,以便我们所有的IO操作(包括同步操作)都封装在单独的任务中,然后通过Task.WhenAll并行执行所有这些任务.我完全可以理解这个想法:我们使用更多的线程,但我们所有的IO操作(我们可以有很多)以最慢的速度执行,但我仍然不确定
我的一位同事重构了我们的控制器方法,以便我们所有的IO操作(包括同步操作)都封装在单独的任务中,然后通过Task.WhenAll并行执行所有这些任务.我完全可以理解这个想法:我们使用更多的线程,但我们所有的IO操作(我们可以有很多)以最慢的速度执行,但我仍然不确定它是否是正确的路径.这是一种有效的方法还是我遗漏了什么?在典型的ASP.Net网站应用程序中使用更多线程的成本是否明显?
这是一些示例代码

public async Task<ActionResult> Foo() {
    var dataATask = _dataARepository.GetDataAsync();
    var dataBTask = Task.Run(_dataBRepository.GetData());
    await Task.WhenAll(dataATask,dataBTask);
    var viewModel = new ViewModel(dataATask.Result,dataBTask.Result);
    return View(viewModel);
}

解决方法

一般来说,你的代码是正常的 – 它会消耗更多的线程和比原来更多的CPU,但除非你的网站负载很重,否则不太可能对整体性能产生重大影响.显然,你需要自己测量它的特定负载(包括5-10x常规流量的某种压力水平负载).

在Task.Run中包装同步方法不是最佳实践(参见Should I expose asynchronous wrappers for synchronous methods?).它可能对你有用,只要为这种行为交易额外的线程是可以接受的.

如果您只剩下一个同步操作,则可以保持同步,并在同步步骤结束时等待剩下的额外线程:

var dataATask = _dataARepository.GetDataAsync();
var dataBTaskResult = _dataBRepository.GetData();
await Task.WhenAll(dataATask); // or just await dataATask if you have only one.
var viewModel = new ViewModel(dataATask.Result,dataBTaskResult);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读