C# 流水线模式在并行ForEach C中的应用#

C# 流水线模式在并行ForEach C中的应用#,c#,asynchronous,parallel-processing,task,parallel.foreach,C#,Asynchronous,Parallel Processing,Task,Parallel.foreach,我唯一的疑问是,在等待流程完成之前,我必须将什么任务添加到任务列表中。或者,如果你有一个不同的方法将是有益的,我基本上想迭代一个ID集合 其中每个ID上有两个进程,一个进程依赖于另一个结果。 第一个任务是在我的本地网络上运行很长时间的任务。根据结果,如果任务返回true,我将向“MyCollection”添加一个新实例。 基于管道模式,现在 所以,控制所有任务直到完成是我的疑问。请参阅示例和注释,谢谢 List<Task> tasks = new List<Task>()

我唯一的疑问是,在等待流程完成之前,我必须将什么任务添加到任务列表中。或者,如果你有一个不同的方法将是有益的,我基本上想迭代一个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());  
List tasks=newlist();
BlockingCollection MyCollection=新建BlockingCollection(IdsCollection.Count);
Parallel.ForEach(IdsCollection,
(Id)=>
{ 
Task task1=Task.Factory.StartNew(()=>
{
//网络上长时间运行的任务
返回剂量法(Id);
});
任务task1\u 1=task1.ContinueWith((isValid)=>
{
if(isValid.Result)
MyCollection.Add(新的MyType(Id));
});
//??我需要同时添加这两个任务还是任务1??
任务。添加(任务1\u 1);
}
);
Task.WaitAll(tasks.ToArray());

是的,添加
task1\u 1
就足够了,没有理由还要显式等待
task1

但是:

  • 这不是管道模式。在那里,管道的每个阶段都是串行执行的,而不是并行执行的
  • 由于#1,没有理由将这两个阶段分开,对这两个阶段都使用一个
    任务将同样有效
  • List
    不是线程安全的,所以您不能像这样从内部
    Parallel.ForEach()
    访问它。这意味着您的代码可能抛出错误结果,或者更糟的是,生成错误结果
  • 如果您要做的只是在其中启动一个
    任务
    并设置其继续,那么使用
    Parallel.ForEach()
    是没有意义的。在这里使用它所获得的只是一些开销
  • <> LI>如果可以,考虑使代码的基于网络的部分异步,然后<代码>等待,它更有效。
    你为什么不只写一个任务呢?
    我唯一的疑问是,我必须在任务列表中添加什么任务才能等待流程完成。
    这取决于你想等待哪些任务。现实一点,我真正的项目做的不止这些,我只是添加了这个虚拟示例。我认为这足以理解我的观点,对它可以在onw任务中完成,但不能在我的实际项目中完成。我添加了task1_1,如上所示,但我不确定这是否正确,因为这是我第一次使用ContinueWith Tasks。
    Tasks
    不是线程安全的。相反,请使用
    task.AwaitAll(Ids.AsParallel.Select(…)