拥有以下代码,如何更新共享变量?
List<Person> list = new List<Person> {new Person {Age = 1}, new Person {Age = 2}, new Person {Age = 5}};
long total = 0;
Parallel.ForEach(list, () => 0, (person, loop, subtotal) =>
{
Add(person, subtotal);
return subtotal;
},
finalResult => Interlocked.Add(ref total, finalResult)
);
public static void Add(Person person, int shared)
{
// Do some work
shared =+ person.Age;
}
由于某种原因,共享回来为0.
答案 0 :(得分:2)
Shared返回0,因为它是以0发送并按值传递的。您需要使用ref关键字,或以其他方式解决此行为(静态变量)。
public static void Add(Person person, ref int shared)
{
// Do some work
shared =+ person.Age;
}
看起来你也有一个问题,就是用'= +'代替'+ ='。
public static void Add(Person person, ref int shared)
{
// You likely meant to do this.
shared += person.Age;
}
答案 1 :(得分:2)
改变你的代码,你会得到预期的结果:
static void Main(string[] args)
{
List<Person> persons = new List<Person>
{
new Person { Age = 1 },
new Person { Age = 2 },
new Person { Age = 5 }
};
long total = 0;
Parallel.ForEach(persons, person => Add(person, ref total));
Console.WriteLine(total);
Console.ReadKey();
}
public static void Add(Person person, ref long shared)
{
// since here you access a shared variabe, we
// can use the Interlocked class in order our operation
// to be atomic.
Interlocked.Add(ref shared, person.Age);
}
答案 2 :(得分:0)
同样的原因它在“常规”C#代码中不起作用...整数是值类型,因此您需要使参数成为ref参数。否则,您只是递增本地副本。此外,您应该使用Interlocked.Increment而不是+ =,否则您可能遇到线程问题,因为+ =不一定是原子的。
答案 3 :(得分:0)
试试这个
int sum = list.AsParallel().Sum(person => person.Age);
结果将是相同的,将使用更少的代码。