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

Parallel.ForEach处理List<string>时返回重复或空数据的问题求解

问题根源

两个核心原因直接导致了你遇到的字符串错乱、集合内容异常问题:

  • 共享msg变量的跨线程读写冲突:你当前的msg是在Parallel.ForEach外部声明的公共变量,所有并行执行的任务都会同时对同一个msg做清空、赋值、拼接操作,不同线程的操作互相穿插覆盖,就会出现单条信息拼接多段其他任务的内容、重复内容等错乱情况。你提到q++逻辑正常,大概率是你已经对q的自增做了线程同步(比如用了Interlocked.Increment),但字符串操作没做同步才会出现差异。
  • response集合非线程安全:常规的List<T>等集合本身不支持多线程同时写入,多个任务同时调用Add方法时会出现内部索引计数错乱,导致元素重复添加、漏加、内容不一致。
修复方案

按照以下两步修改即可解决问题:

  1. 将msg改为并行任务内部的局部变量,每个线程处理单独条目时只用自己的局部变量,完全避免跨线程共享冲突。
  2. 改用线程安全集合存储处理过程中的日志,并行执行完成后再统一整理到最终返回的response中,避免多线程写入普通集合的异常。

修复后的参考代码如下:

// 引入线程安全集合存处理日志,无需额外加锁
ConcurrentBag<string> processLogs = new ConcurrentBag<string>();
int q = 0;

var parallelResult= Parallel.ForEach(myList,
    new ParallelOptions
    {
        MaxDegreeOfParallelism = Convert.ToInt32(Math.Ceiling(
            (Environment.ProcessorCount * 0.75) * 3.0))
    },
    item => {
        // msg改为局部变量,每个线程独立使用,不会和其他线程冲突
        string msg = item.fullName;
        var balance = users.balance(item.id);
        if (balance.amount > 0 && balance.isReady)
        {
            var sendResponse = users.send(item.id, balance.amount);
            tbeResponse data = JsonConvert.DeserializeObject<tbeResponse>(sendResponse);

            if (data.success)
            {
                _context.users.Add(item);
                msg += " added : " + sendResponse;
                // 保证q自增的线程安全,如果你之前已经处理过可以保留原有逻辑
                Interlocked.Increment(ref q);
            }
            else
            {
                msg += "could not be added: " + sendResponse;
            }
        }
        else
        {
            msg += " balance=0";
        }
        processLogs.Add(msg);
    });

if(parallelResult.IsCompleted)
    _context.SaveChanges();

// 并行处理完成后统一把日志写入response
foreach(var log in processLogs)
{
    response.Add(log);
}
response.Add($"{q} were added to the database. And need to be signed");
return Ok(response);

额外注意

如果你用的_context是EF的DbContext,需要注意DbContext本身也不支持多线程并行操作,当前并行调用Add的逻辑也有概率触发异常,如果后续出现数据存储相关问题,建议把Add操作移到并行执行完成后统一处理,或者对Add操作加锁。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 22:24:00