并行控制增量变量

时间:2014-07-08 14:39:14

标签: c# task-parallel-library task parallel.foreach

我有以下TPL功能:

int arrayIndex = 0;

Dictionary < string, int > customModel = new Dictionary < string, int > ();

    Task task = Task.Factory.StartNew(() =>

        // process each employee holiday

        Parallel.ForEach < EmployeeHolidaysModel > (holidays,
            new ParallelOptions() {
                MaxDegreeOfParallelism = System.Enviroment.ProcessorCount
            },
            item => {

                customModel.Add(item.HolidayName, arrayIndex);

                // increment the index
                arrayIndex++;

            })
    );

    //wait for all Tasks to finish
    Task.WaitAll(task);

问题是由于并行性,arrayIndex将不具有唯一值。

有没有办法可以控制arrayIndex变量,所以在并行任务之间值是唯一的?

  

基本上在我的customModel我不能有重复的arrayIndex值。

感谢任何帮助。

2 个答案:

答案 0 :(得分:1)

这里有三个问题:

  1. 您正在写共享变量(int和字典)。这是不安全的。您必须同步或使用线程安全的集合。
  2. 您每次迭代所做的工作量非常小,以至于并行性的开销会大几个数量级。这不是并行性的好例子。预计会出现重大减速。
  3. 你开始一项任务,然后等待它。你打算做什么才能做到这一点?
  4. 我认为你需要一个基本的tutorial about threading。这些是非常基本的问题。根据您目前的知识水平,您将无法使用多线程......

答案 1 :(得分:1)

您需要使用Interlocked.Increment()。你应该也可以使用ConcurrentDictionary来保证安全,假设你不只是为这个问题做了样本代码。

同样,此处的任务也不是必需的,因为您只是等待它完成填充customModel。显然,您的场景可能更复杂。

但考虑到你发布的代码,我会做类似的事情:

int arrayIndex = 0;

ConcurrentDictionary<string,int> customModel
        = new ConcurrentDictionary<string,int>();

Parallel.ForEach<EmployeeHolidaysModel>(
    holidays,
    new ParallelOptions() {
        MaxDegreeOfParallelism = System.Enviroment.ProcessorCount
    },
    item => customModel.TryAdd(
        item.HolidayName,
        Interlocked.Increment(ref arrayIndex)
    )
);

NowYouCanDoSomethingWith(customModel);