非阻塞与并行(TPL)的互锁使用问题

D J*_*D J 1 c# multithreading task-parallel-library

我对多线程中代码的准确性感到困惑,因为有些时候我得到了错误的结果.

看起来可能会失败.下面是代码.

public class MyKeyValue
{
    public double Key { get; set; }
    public double Value { get; set; }
}

public class CollMyKeyValue : List<MyKeyValue>
{
    public void SumUpValues(CollMyKeyValue collection)
    {
        int count =0;
        Parallel.For(count, this.Count, 
        (i) => 
        {
            this[count].Value = this[count].Value + collection[count].Value;
            Interlocked.Increment(ref count);
        });  
    }
}
Run Code Online (Sandbox Code Playgroud)

假设两个集合中的密钥相同.

我想将一个集合的值添加到另一个集合中.它安全吗?

我没有把this[count].Value = this[count].Value + collection[count].Value;线程安全块.

J..*_*... 5

只需删除互锁增量:

public void SumUpValues(CollMyKeyValue collection)
{
    //int count =0;
    Parallel.For(0, this.Count, 
        (i) => 
            {
                this[i].Value = this[i].Value + collection[i].Value;
                //Interlocked.Increment(ref count);
            });  
}
Run Code Online (Sandbox Code Playgroud)

您的版本正在改变循环内的索引变量.该For循环自动执行此操作; 在并行版本中,每个线程都有一个i(或一组i)要做,所以在循环中递增是没有意义的.


Sri*_*vel 5

不确定你要做什么.但我想你的意思是这个.

public void SumUpValues(CollMyKeyValue collection)
{
    Parallel.For(0, this.Count, (i) =>
    {
        this[i].Value += collection[i].Value;
    });
}
Run Code Online (Sandbox Code Playgroud)

第一个参数说明从Parallel.For哪里开始,改变这是没有意义的.你得到i循环体的参数,它将告诉你你在哪个迭代.