C# 如何为代码提供线程安全性?

C# 如何为代码提供线程安全性?,c#,multithreading,C#,Multithreading,我想把上面的代码并行化。我必须对count()从0到10^9-1进行10亿次运算。count()函数本身不与其他线程共享数据。但是,将结果从count()添加到total不是线程安全的-每次运行程序时,结果都不同total必须存储一些不能存储在int中的整数值。我的问题有什么解决方案吗?尝试以下方法: 您也可以使用标准锁() 您也可以使用标准的lock()。并行LINQ使这变得很容易: using System; using System.Collections.Generic; using

我想把上面的代码并行化。我必须对
count()
从0到10^9-1进行10亿次运算。
count()
函数本身不与其他线程共享数据。但是,将结果从
count()
添加到
total
不是线程安全的-每次运行程序时,结果都不同
total
必须存储一些不能存储在int中的整数值。我的问题有什么解决方案吗?

尝试以下方法:

您也可以使用标准锁()


您也可以使用标准的lock()。

并行LINQ使这变得很容易:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Program
{
    class Program
    {
        static long total = 0;
        static long count(int row)
        {
            /* do_something .. every operation is thread safe here */
            return somevalue;
        }
        static void Main(string[] args)
        {
            Parallel.For(0, 10000000, i => //some big limit to test threading is working
            {
                total += count(i);
                // however, collecting 'somevalue' from 'count()' operation isn't thread safe.
            });

            Console.WriteLine(total);
        }
    }
}

并行LINQ使这变得简单:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Program
{
    class Program
    {
        static long total = 0;
        static long count(int row)
        {
            /* do_something .. every operation is thread safe here */
            return somevalue;
        }
        static void Main(string[] args)
        {
            Parallel.For(0, 10000000, i => //some big limit to test threading is working
            {
                total += count(i);
                // however, collecting 'somevalue' from 'count()' operation isn't thread safe.
            });

            Console.WriteLine(total);
        }
    }
}
这是一个用于组合投影和求和的单行线

ParallelEnumerable.Range(0, 10000000).Select(i=>count(i)).Sum()
这是一个用于组合投影和求和的单行线

ParallelEnumerable.Range(0, 10000000).Select(i=>count(i)).Sum()

并行LINQ,使用
Select(i=>count(i)).Sum()
应该工作并行LINQ,使用
Select(i=>count(i)).Sum()
应该工作当锁和原子增量修复正确性问题时,它们极大地损害了性能。如果count是一个执行时间很短的函数,那么结果可能比serial慢。如果计数较慢,您可能会看到一些加速。添加更多线程也不会有任何好处。虽然锁和原子增量解决了正确性问题,但它们极大地损害了性能。如果count是一个执行时间很短的函数,那么结果可能比serial慢。如果计数较慢,您可能会看到一些加速。添加更多线程也不会有任何好处。