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

如何提升C#批量文档检查for循环的执行性能?

优化方案

当前代码的核心性能瓶颈在于串行执行每个数据库查询操作——数据库IO属于高延迟操作,串行处理会累积所有请求的延迟,导致数据量越大耗时越长。以下是针对性的优化手段:

1. 并行异步处理(快速见效)

如果查询方法提供异步版本(如AksBelgeKontroluAsync、TckkBelgeKontroluAsync),优先采用异步并行批量处理,避免阻塞线程池:

internal async Task<DtResult> documentCheckListAsync(AksBelgeKontrolData[] belgeList, string dmUser = null)
{
    if (string.IsNullOrEmpty(dmUser) || CurrentDomain == "nvi.local")
        dmUser = "MERNIS\\************";

    Stopwatch sw = new Stopwatch();
    sw.Start();

    // 批量创建异步任务
    var tasks = belgeList.Select(belgeData => belgeData.AnaBelgeTur switch
    {
        AnaBelgeTur.AksYeniBelge => GdAksYeniQueries.AksBelgeKontroluAsync(belgeData, dmUser),
        AnaBelgeTur.TckkYeniBelge => GdTckkYeniQueries.TckkBelgeKontroluAsync(belgeData, dmUser),
        _ => Task.FromResult(false) // 对应默认状态
    }).ToList();

    // 等待所有任务完成
    var results = await Task.WhenAll(tasks);

    // 将结果映射回原数组
    for (int i = 0; i < belgeList.Length; i++)
    {
        belgeList[i].BelgeVar = results[i];
    }

    sw.Stop();
    var test = sw.ElapsedMilliseconds;

    return new DtResult
    {
        ResultState = DtResultState.Ok,
        BelgeKontrolListesi = belgeList
    };
}

若没有异步版本,可使用Parallel.For实现并行处理(注意:需确保查询方法线程安全,当前场景下每个元素独立修改,无线程冲突):

internal DtResult documentCheckList(AksBelgeKontrolData[] belgeList, string dmUser = null)
{
    if (string.IsNullOrEmpty(dmUser) || CurrentDomain == "nvi.local")
        dmUser = "MERNIS\\************";

    Stopwatch sw = new Stopwatch();
    sw.Start();

    // 并行遍历数组处理每个元素
    Parallel.For(0, belgeList.Length, i =>
    {
        var belgeData = belgeList[i];
        belgeList[i].BelgeVar = belgeData.AnaBelgeTur switch
        {
            AnaBelgeTur.AksYeniBelge => GdAksYeniQueries.AksBelgeKontrolu(belgeData, dmUser),
            AnaBelgeTur.TckkYeniBelge => GdTckkYeniQueries.TckkBelgeKontrolu(belgeData, dmUser),
            _ => false
        };
    });

    sw.Stop();
    var test = sw.ElapsedMilliseconds;

    return new DtResult
    {
        ResultState = DtResultState.Ok,
        BelgeKontrolListesi = belgeList
    };
}

2. 批量查询优化(根本性提升)

如果可以修改查询方法的实现,建议将同类型的数据批量传入,通过一次数据库查询返回所有结果,大幅减少数据库往返次数:

首先新增批量查询方法示例:

// 示例:批量处理AksYeniBelge类型的查询
public static Dictionary<int, bool> AksBelgeKontroluBatch(AksBelgeKontrolData[] belgeDatas, string dmUser)
{
    // 实现批量查询逻辑,以数据ID为键返回对应结果
}

然后在主方法中分组处理:

internal DtResult documentCheckList(AksBelgeKontrolData[] belgeList, string dmUser = null)
{
    if (string.IsNullOrEmpty(dmUser) || CurrentDomain == "nvi.local")
        dmUser = "MERNIS\\************";

    Stopwatch sw = new Stopwatch();
    sw.Start();

    // 按文档类型分组
    var aksGroup = belgeList.Where(x => x.AnaBelgeTur == AnaBelgeTur.AksYeniBelge).ToArray();
    var tckkGroup = belgeList.Where(x => x.AnaBelgeTur == AnaBelgeTur.TckkYeniBelge).ToArray();

    // 批量查询每组数据
    var aksResults = GdAksYeniQueries.AksBelgeKontroluBatch(aksGroup, dmUser);
    var tckkResults = GdTckkYeniQueries.TckkBelgeKontroluBatch(tckkGroup, dmUser);

    // 将结果赋值回原数组
    foreach (var data in aksGroup)
    {
        data.BelgeVar = aksResults[data.Id]; // 假设Id为数据唯一标识
    }
    foreach (var data in tckkGroup)
    {
        data.BelgeVar = tckkResults[data.Id];
    }

    sw.Stop();
    var test = sw.ElapsedMilliseconds;

    return new DtResult
    {
        ResultState = DtResultState.Ok,
        BelgeKontrolListesi = belgeList
    };
}

3. 细节优化

  • 用switch替代if-else:多分支判断时switch性能更优,代码可读性也更强
  • 减少数组索引重复访问:循环中直接获取元素后操作,避免反复通过索引查找数组元素
  • 数据库连接池配置:确保数据库连接池的Max Pool Size参数足够,避免并行时连接耗尽

内容的提问来源于stack exchange,提问作者Büşra Güler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 15:40:01