C# PLINQ订单如何输入

C# PLINQ订单如何输入,c#,multithreading,plinq,C#,Multithreading,Plinq,如果我在IEnumerable(列表)中有以下顺序: 1-2-3-4-5 如果我在上面运行PLINQ查询,请说: list.AsParallel().AsOrdered().WithDegreeOfParallelism(10).Select( s => SomeDelegateFunction(s)).AsSequential().ToList(); 对于上面的查询,我在日志记录(委托函数内部)中看到它使用多个线程,但不维护列表的处理顺序。 但是,对于以

如果我在IEnumerable(列表)中有以下顺序:

1-2-3-4-5

如果我在上面运行PLINQ查询,请说:

list.AsParallel().AsOrdered().WithDegreeOfParallelism(10).Select(
                s => SomeDelegateFunction(s)).AsSequential().ToList();
对于上面的查询,我在日志记录(委托函数内部)中看到它使用多个线程,但不维护列表的处理顺序。 但是,对于以下查询,我确实维护了序列,但使用单个线程执行整个操作:

list.AsParallel().AsOrdered().WithDegreeOfParallelism(10).AsSequential().Select(
               s => SomeDelegateFunction(s)).ToList();
两个查询之间的区别是“AsSequential()”,在第二个查询中,我遇到的问题是,当我使用AsSequential()时:

1-为什么不使用多线程?它可以将工作分解为:

1 - 2 (Give it to thread 1)
3 - 4 - 5 (Give it to thread 2)
相反,它做1-2-3-4-5(按顺序),但它在一个线程上-为什么

基本上,我需要按照列表作为输入的顺序处理列表,但需要在多个线程上处理

有什么想法吗

基本上,我需要按照列表作为输入的顺序处理列表,但需要在多个线程上处理

这些是相互排斥的要求。你可以做一个或另一个,但决不能两者兼而有之

如果您不关心项目的处理顺序,您只需要确保最终结果是对象按照它们第一次进入的顺序,因为您可以执行以下操作:

var list = new List<int> { 1, 2, 3, 4, 5 };

Parallel.For(0, list.Count, i =>
{
    list[i] = Process(i);
});
Enumerable.Range(0, list.Count)
    .AsParallel()
    .WithDegreeOfParallelism(10)
    .ForAll(i =>
    {
        list[i] = Process(i);
    });
基本上,我需要按照列表作为输入的顺序处理列表,但需要在多个线程上处理

这些是相互排斥的要求。你可以做一个或另一个,但决不能两者兼而有之

如果您不关心项目的处理顺序,您只需要确保最终结果是对象按照它们第一次进入的顺序,因为您可以执行以下操作:

var list = new List<int> { 1, 2, 3, 4, 5 };

Parallel.For(0, list.Count, i =>
{
    list[i] = Process(i);
});
Enumerable.Range(0, list.Count)
    .AsParallel()
    .WithDegreeOfParallelism(10)
    .ForAll(i =>
    {
        list[i] = Process(i);
    });

多线程生产者-消费者模式允许您确保以相同的顺序处理项目,同时允许并发处理项目。但是,如果您需要确保每个项目的处理在下一个项目的处理开始之前完成,那么正如Servy所说,您就不走运了

在生产者-消费者模式中,为了维护订单,可以使用线程安全队列。一个或多个生产者线程将要处理的项目排队;在这种情况下,您将有一个生产者按顺序将项目从列表传递到队列。然后,多个使用者线程可以按顺序将项目出列


有关更多信息,请参阅。

多线程生产者-消费者模式允许您确保以相同的顺序处理项目,同时允许同时处理项目。但是,如果您需要确保每个项目的处理在下一个项目的处理开始之前完成,那么正如Servy所说,您就不走运了

在生产者-消费者模式中,为了维护订单,可以使用线程安全队列。一个或多个生产者线程将要处理的项目排队;在这种情况下,您将有一个生产者按顺序将项目从列表传递到队列。然后,多个使用者线程可以按顺序将项目出列


有关更多信息,请参阅。

回答第一个问题

为什么不使用多线程

这就是
AsSequential()
所做的与
AsParallel()
所做的恰恰相反。
aspallel()
对有序可枚举
IEnumerable
进行
并行查询
以允许在多个线程中并行执行
AsSequential()
用于将并行执行的结果合并到一个可枚举项中,并返回调用线程

回答你的第二个问题

它可以将工作分解为:

1 - 2 (Give it to thread 1)
3 - 4 - 5 (Give it to thread 2)
是的,它可以,但在并行执行此序列的情况下,3可能会比1更早处理,而不是顺序执行


然而,您可以显式地控制
PLINQ
如何将序列分解为多个分区。因此,您可以控制数据在多个线程之间的分布方式。请参见第一个问题的答案

为什么不使用多线程

这就是
AsSequential()
所做的与
AsParallel()
所做的恰恰相反。
aspallel()
对有序可枚举
IEnumerable
进行
并行查询
以允许在多个线程中并行执行
AsSequential()
用于将并行执行的结果合并到一个可枚举项中,并返回调用线程

回答你的第二个问题

它可以将工作分解为:

1 - 2 (Give it to thread 1)
3 - 4 - 5 (Give it to thread 2)
是的,它可以,但在并行执行此序列的情况下,3可能会比1更早处理,而不是顺序执行


然而,您可以显式地控制
PLINQ
如何将序列分解为多个分区。因此,你可以控制自己如何在多个线程之间分配数据。请看

啊……理论上,分工可以按顺序进行,然后并行处理-正确吗?@MurtazaMandvi在我引用你的声明中特别指出,它们需要按其出现的顺序进行处理。这使得这个问题无法并行解决。如果您希望它以任何顺序处理这些结果,但要确保当它们全部完成时,最终结果的返回顺序与第一次收到它们时的顺序相同,那么这是可能的,但这不是您所要求的。您的代码可以工作,但我认为使用
AsOrdered()
是一个更简洁的选择:您不必处理索引,结果将是相同的。@svick我不太使用PLINQ,所以我只做了我知道会起作用的事情。如果有基于PLINQ设计的更合适的方法,请务必发布。@Servy更合适的方法是问题的第一个片段。但是OP不喜欢它,因为它“没有维护列表的处理顺序”。正如你所说,这并不意味着