繁体   English   中英

并行使用ForEach C#的管道模式

[英]Pipeline pattern using in parallel ForEach C#

我唯一的疑问是,我必须添加什么任务到任务列表中才能等待过程完成。 或者,如果您采用其他方法会有所帮助,那么我基本上要迭代一组ID,其中在每个ID上我有两个过程,一个取决于另一个结果。 第一项任务是通过我的本地网络长期运行的任务。 并且根据结果,如果该任务返回true,我将向“ MyCollection”添加一个新实例。 现在基于管道模式。

因此,控制所有任务等到它们完成才是我的疑问。请查看示例和评论,谢谢。

List<Task> tasks = new List<Task>();
BlockingCollection<MyType> MyCollection = new BlockingCollection<MyType>(IdsCollection.Count);

Parallel.ForEach(IdsCollection,  
                        (Id) => 
                        { 
                             Task<bool> task1 = Task.Factory.StartNew(() => 
                             {
                                 //long running task over the network
                                 return DoSmething(Id);
                             });

                             Task task1_1 = task1.ContinueWith((isValid) =>
                             {
                                 if (isValid.Result)
                                     MyCollection.Add(new MyType(Id));
                             });
                             // ??? do I need to Add both or the task1 ??
                             tasks.Add(task1_1); 
                        }
             );

        Task.WaitAll(tasks.ToArray());  

是的,添加task1_1就足够了,没有理由也明确地等待task1

但:

  1. 这不是管道模式。 在那里,流水线的每个阶段都是串行执行的,而不是并行执行的。
  2. 由于是#1,因此没有理由将各个阶段分开,因为对两个Task都使用一个Task也是一样。
  3. List<T>不是线程安全的,因此您不能像这样从Parallel.ForEach()内部访问它。 这意味着您的代码很可能抛出,或者更糟的是,产生不正确的结果。
  4. 如果您要做的只是在其中启动一个Task并设置其延续性,则使用Parallel.ForEach()没有任何意义。 您在这里使用它所获得的一切只是一些开销。
  5. 如果可以,请考虑使代码的基于网络的部分异步,然后await它,这样会更高效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM