在Parallel.For中控制执行

时间:2016-01-22 19:35:16

标签: c# .net multithreading

在这个并行执行中:

         Parallel.For(0, 100, i =>
         {
             Console.WriteLine(i);
         });

我试图获得下面通常循环的相同值,所以" i"总是按顺序给出,0,1,2,3,...,100

        for(int i=0; i <=100; i++)
        {
            Console.WriteLine(i);
        }

这是可能的,我如何控制这个并行执行索引的顺序?

3 个答案:

答案 0 :(得分:1)

如果你想在i完成后开始i - 1的执行,那么就没有并行性了,使用并行循环是没有意义的。

一个聪明的答案是构建一个字符串,其中101个数字由换行符分隔,然后打印出来。但这并不能帮助你理解我的假设。

答案 1 :(得分:1)

一旦涉及线程,就不再保证执行顺序。通过同步所有内容,您可以在技术上获得您所要求的结果,如下所示:

int actualIndex = 0;
var lockObject = new object();
Parallel.For(0, 100, i =>
{
    lock(lockObject) Console.WriteLine(actualIndex++); 
});

但是,这样做只会增加并行性的开销,然后确保一次只有一个线程正在做某事 - 换句话说,它比仅仅执行常规{{1}更多更糟 } loop!

如果你需要连续发生的事情,你可以做的最好的事情是通过for之类的同步进行序列化,或者......简单地连续进行。

你到底想要完成什么?

答案 2 :(得分:0)

如果您只想按升序排列结果,那么这可能对您有用:

var results = new Dictionary<int>();
object lock = new object();
Parallel.For(0, 100, i =>
         {
             // here code runs in parallel
             lock(lock) { 
                // here code runs sequentially
                results[i]; 
             }
         });

// results from 0..100
var r = results.OrderBy(x => x.Key).Select(x => x.Value).ToList();

lock创建了所谓的临界区 - 内部lock代码块可能只是一个线程,其他线程必须等待。

并行编程是一个庞大而复杂的主题,这是我读过的C#程序员的最佳课程http://www.albahari.com/threading/part5.aspx