Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/279.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Parallel.ForEach不更新共享变量_C#_Parallel Processing_Parallel.foreach - Fatal编程技术网

C# Parallel.ForEach不更新共享变量

C# Parallel.ForEach不更新共享变量,c#,parallel-processing,parallel.foreach,C#,Parallel Processing,Parallel.foreach,有了下面的代码,我如何更新共享变量 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) =>

有了下面的代码,我如何更新共享变量

     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;
    }
List List=newlist{new Person{Age=1},new Person{Age=2},new Person{Age=5};
长总计=0;
Parallel.ForEach(list,()=>0,(person,loop,subtotal)=>
{
加(人,小计);
返回小计;
},
finalResult=>Interlocked.Add(参考总计,finalResult)
);
公共静态无效添加(个人,整数共享)
{
//做些工作
共享=+个人年龄;
}

出于某种原因,shared返回为0

同样的原因,它在“常规”C#代码中不起作用。。。整数是值类型,因此需要将参数设置为ref参数。否则,您只是增加本地副本。另外,您应该使用Interlocked.Increment而不是+=,否则您可能会遇到线程问题,因为+=不一定是原子的。

同样的原因,它在“常规”C#代码中不起作用。。。整数是值类型,因此需要将参数设置为ref参数。否则,您只是增加本地副本。另外,您应该使用Interlocked.Increment而不是+=,否则您可能会遇到线程问题,因为+=不一定是原子的。

共享返回为0,因为它作为0发送,并通过值传递。您需要使用关键字,或者以其他方式解决此行为(静态变量)

看起来您在使用'=+'代替'+='时也遇到了问题

public static void Add(Person person, ref int shared)
{
    // You likely meant to do this.
    shared += person.Age;
}

Shared返回为0,因为它以0的形式发送,并通过值传递。您需要使用关键字,或者以其他方式解决此行为(静态变量)

看起来您在使用'=+'代替'+='时也遇到了问题

public static void Add(Person person, ref int shared)
{
    // You likely meant to do this.
    shared += person.Age;
}

稍微更改一下代码,您将获得预期的结果:

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);
}
static void Main(字符串[]args)
{
名单人员=新名单
{
新人{Age=1},
新人{Age=2},
新人{年龄=5}
};
长总计=0;
Parallel.ForEach(persons,person=>Add(person,ref-total));
控制台写入线(总计);
Console.ReadKey();
}
公共静态无效添加(个人,参考长期共享)
{
//既然您在这里访问共享变量,我们
//可以使用联锁类来进行我们的操作
//是原子的。
联锁。添加(参考共享,人。年龄);
}

稍微更改一下您的代码,您将获得预期的结果:

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);
}
static void Main(字符串[]args)
{
名单人员=新名单
{
新人{Age=1},
新人{Age=2},
新人{年龄=5}
};
长总计=0;
Parallel.ForEach(persons,person=>Add(person,ref-total));
控制台写入线(总计);
Console.ReadKey();
}
公共静态无效添加(个人,参考长期共享)
{
//既然您在这里访问共享变量,我们
//可以使用联锁类来进行我们的操作
//是原子的。
联锁。添加(参考共享,人。年龄);
}
试试这个

int sum = list.AsParallel().Sum(person => person.Age);
结果将是相同的,使用的代码将更少。

试试这个

int sum = list.AsParallel().Sum(person => person.Age);

结果将是相同的,使用更少的代码。

即使您解决了
ref小计
问题,这也行不通。你有一个非常明显的比赛条件。您不断更新和读取一个值。那么我如何跟踪共享变量?@BobSwanson一开始不会并行化总和。这比在单个线程中求和要慢得多。除了速度快得多之外,它还将更简单、更不容易出错、更易于维护,等等。即使您解决了
ref subtotal
问题,这也行不通。你有一个非常明显的比赛条件。您不断更新和读取一个值。那么我如何跟踪共享变量?@BobSwanson一开始不会并行化总和。这比在单个线程中求和要慢得多。除了速度更快之外,它还更简单、更不容易出错、更易于维护,等等。您大概打算使用+=?正如你将“共享”设置为“年龄”的正值一样?啊,成功了,需要锁定吗?因为它是共享的?大概您打算使用+=?正如你将“共享”设置为“年龄”的正值一样?啊,成功了,需要锁定吗?因为它是共享的?如果我的共享不是int或long,而是十进制,我会使用lock()吗?@BobSwanson正是:)如果我的共享不是int或long,而是十进制,我会使用lock()吗?@BobSwanson正是:)