【问题标题】:How to execute Parallel.For Loop and Parallel.ForEach loop in sequence如何依次执行 Parallel.For 循环和 Parallel.ForEach 循环
【发布时间】:2015-12-19 21:35:28
【问题描述】:

我知道如何编写 Parallel.ForParallel.ForEach 循环。以下是它们的示例代码:

Parallel.For(0,10, (int i) = > 
{
     Console.Writeline(i);
});  

Parallel.ForEach(fruits, fruit =>  
{  
     Console.WriteLine("Fruit Name: {0}, Thread Id= {1}", fruit, Thread.CurrentThread.ManagedThreadId);      
});

但是这两个代码示例的问题是循环不按顺序执行。如何让它们按顺序执行?我从人们那里听说你必须锁定一个对象,然后才有可能。我已经尝试搜索并尝试了很多代码示例但没有用。

此外,我想知道按顺序执行的并行循环的性能是否会降低?如果没有,为什么没有?因为锁定,会导致我拙见的延迟。

就我对并行编程的理解而言,调度程序在运行时进行调度。谁能说出 .NET IDE 使用什么算法/策略在多个内核上调度代码?其货到里外并行编程。

【问题讨论】:

  • 它们将按顺序执行,首先是 For,然后是 ForEach。但不保证它们在自己作用域内的结果是按顺序排列的。
  • 如果要顺序执行,请使用forforeach,集合排序的任何先决条件都会降低在Parallel 中运行时的性能,甚至可能比顺序循环慢

标签: c# task-parallel-library


【解决方案1】:

让线程并行和顺序运行对你来说真的没有意义。

如果Thread 3Thread 1 之前完成会发生什么?如果你要阻止Thread 3 并让它等到Thread 1 完成,那么使用线程有什么意义呢?

但是,如果您希望批量按顺序完成,这是可能的,但仍然不理想。

我的意思是,如果您有一个列表 [1,2,3,4,5,6,7,8,9,10] 运行 2 个线程,您可以确保 12 在任何其他项目之前处理,依此类推。为此,您可以使用以下内容:

void Main()
{
    var items = Enumerable.Range(1, 100);
    const int numThreads = 4;

    foreach(var batch in items.Batch(numThreads))
    {
        var threads = batch.Select(item => {
            return new Thread(() => Console.WriteLine(item));
        }).ToList();

        threads.ForEach(t => t.Start());
        threads.ForEach(t => t.Join());
    }
}

public static class Ext
{
    public static IEnumerable<IEnumerable<TSource>> Batch<TSource>(
                    this IEnumerable<TSource> source, int size)
    {
        TSource[] bucket = null;
        var count = 0;

        foreach (var item in source)
        {
            if (bucket == null)
                bucket = new TSource[size];

            bucket[count++] = item;
            if (count != size)
                continue;

            yield return bucket;

            bucket = null;
            count = 0;
        }

        if (bucket != null && count > 0)
            yield return bucket.Take(count);
    }
}

批量扩展方法取自this answer

【讨论】:

    猜你喜欢
    • 2021-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-04
    • 2014-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多