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

C#:异步运行此代码的不同方法?

发布时间:2020-12-16 00:15:38 所属栏目:百科 来源:网络整理
导读:我有这个代码 Liststring myList = new Liststring();myList.AddRange(new MyClass1().Load());myList.AddRange(new MyClass2().Load());myList.AddRange(new MyClass3().Load());myList.DoSomethingWithValues(); 什么是异步运行任意数量的Load()方法的最佳
我有这个代码

List<string> myList = new List<string>();

myList.AddRange(new MyClass1().Load());
myList.AddRange(new MyClass2().Load());
myList.AddRange(new MyClass3().Load());

myList.DoSomethingWithValues();

什么是异步运行任意数量的Load()方法的最佳方法,然后确保在所有异步线程完成时运行DoSomethingWithValues()(当然每次回调发生时都不会增加变量并等待== 3)

解决方法

Ani的概念解决方案可以更简洁地编写:

new ILoadable[] { new MyClass1(),new MyClass2(),new MyClass3() }
    .AsParallel().SelectMany(o => o.Load()).ToList()
    .DoSomethingWithValues();

这是我的首选解决方案:声明式(AsParallel)和简洁.

当以这种方式编写时,Reed的解决方案如下所示:

new ILoadable[] { new MyClass1(),new MyClass3() }
    .Select(o=>Task.Factory.StartNew(()=>o.Load().ToArray())).ToArray()
    .SelectMany(t=>t.Result).ToList()
    .DoSomethingWithValues();

请注意,两个ToArray调用可能都是必要的.如果o.Load是懒惰的(通常它可以是YMMV),第一次调用是必要的,以确保在后台任务中完成o.Load的评估.第二次调用是必要的,以确保在调用SelectMany之前完全构造了任务列表 – 如果不这样做,那么SelectMany将尝试仅在必要时迭代其源 – 即它不会迭代到必须进行的第二项任务,直到计算出第一项任务的结果为止.实际上,您正在启动任务,但随后又一个接一个地执行它们 – 将后台任务转换回严格的顺序执行.

请注意,第二个声明性较小的解决方案存在更多陷阱,需要进行更彻底的分析以确保它是正确的 – 即,这样可维护性较差,但仍比手动线程更好.顺便说一句,您可以放弃对.ToList的调用 – 这取决于DoSomethingWithValues的细节 – 以获得更好的性能,从而您的最终处理可以访问第一个值,因为它们无需等待所有要完成的任务或并行枚举.这甚至更短!

(编辑:李大同)

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

    推荐文章
      热点阅读