我对多线程中代码的准确性感到困惑,因为有些时候我得到了错误的结果。
看起来可能会失败。以下是代码。
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);
});
}
}
假设两个集合中的密钥相同。
我想将一个集合的值添加到另一个集合中。是安全吗?
我没有将this[count].Value = this[count].Value + collection[count].Value;
放在线程安全块中。
答案 0 :(得分: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);
});
}
您的版本正在改变循环内的索引变量。 For
循环自动执行此操作;在并行版本中,每个线程都要获得i
(或i
的集合),因此在循环中递增是没有意义的。
答案 1 :(得分:5)
不确定你要做什么。但我想你的意思是这个。
public void SumUpValues(CollMyKeyValue collection)
{
Parallel.For(0, this.Count, (i) =>
{
this[i].Value += collection[i].Value;
});
}
第一个参数表示Parallel.For
从哪里开始,改变它是没有意义的。你得到i
作为循环体的参数,它将告诉你你在哪个迭代。