You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用Tasks时Linq Sum()会输出不同结果?

嘿,这个问题我之前也踩过坑,大概率是你在多任务里共享了一个可变的累加变量,而且没做线程同步导致的竞态条件!

问题核心原因分析

这种情况最常见的场景是:你没有让每个Task独立计算Enumerable.Range的Sum结果,而是把所有Task的累加操作都写到同一个共享变量里,并且没做任何线程安全保障。

举个典型的错误代码例子:

var numbers = Enumerable.Range(1, 1000);
int total = 0; // 多个Task共享的可变变量
var tasks = new List<Task>();

// 启动多个任务同时累加
for (int i = 0; i < 4; i++)
{
    tasks.Add(Task.Run(() =>
    {
        foreach (var num in numbers)
        {
            total += num; // 这里的+=不是原子操作!
        }
    }));
}

Task.WaitAll(tasks.ToArray());
Console.WriteLine(total); // 每次运行结果都可能不一样,远小于预期值

为什么结果会不稳定?因为total += num这个操作本质上是三步:

  1. 读取total的当前值
  2. 加上num得到新值
  3. 将新值写回total

当多个线程同时执行这三步时,就会出现竞态冲突:比如线程A刚读取了total=100,还没来得及写回新值,线程B也读取了total=100,两个线程各自计算后写回,最终total的值会被其中一个线程的结果覆盖,导致部分累加值丢失。

而如果是每个Task独立调用numbers.Sum()再汇总结果,完全不会有问题——因为Linq的Sum()方法在执行时,会创建自己的局部累加变量,每个Task的Sum操作完全独立,不会互相干扰:

var numbers = Enumerable.Range(1, 1000);
var tasks = new List<Task<int>>();

for (int i = 0; i < 4; i++)
{
    tasks.Add(Task.Run(() => numbers.Sum())); // 每个任务独立计算Sum
}

var results = Task.WhenAll(tasks).Result;
int total = results.Sum(); // 汇总独立的结果
Console.WriteLine(total); // 结果稳定符合预期
解决办法

如果确实需要在多线程中共享累加变量,你需要用线程安全的方式操作:

  • 使用Interlocked.Add方法,它是原子操作,能保证读取、修改、写回的过程不会被其他线程打断:
var numbers = Enumerable.Range(1, 1000);
int total = 0;
var tasks = new List<Task>();

for (int i = 0; i < 4; i++)
{
    tasks.Add(Task.Run(() =>
    {
        foreach (var num in numbers)
        {
            Interlocked.Add(ref total, num); // 原子累加
        }
    }));
}

Task.WaitAll(tasks.ToArray());
Console.WriteLine(total); // 结果正确稳定
  • 或者使用lock语句,锁定共享变量的操作区域,同一时间只有一个线程能执行累加:
var numbers = Enumerable.Range(1, 1000);
int total = 0;
object lockObj = new object(); // 用于锁定的对象
var tasks = new List<Task>();

for (int i = 0; i < 4; i++)
{
    tasks.Add(Task.Run(() =>
    {
        foreach (var num in numbers)
        {
            lock(lockObj)
            {
                total += num;
            }
        }
    }));
}

Task.WaitAll(tasks.ToArray());
Console.WriteLine(total); // 结果正确稳定

内容的提问来源于stack exchange,提问作者Khawaja Asim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:17:45