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

BackgroundWorker调用ReportProgress抛出TargetInvocationException问题求解

问题原因及修复方案

核心问题点

  • ReportProgress 方法要求传入的进度百分比范围必须是 0~100,你当前直接传入单文件的行号 i,如果文件行数超过 100,传入值就会超出合法范围,后续给进度条赋值时会触发越界异常。
  • 进度计算逻辑完全错误:你没有统计所有待处理文件的总行数,仅按单文件的行号上报进度,无法反映整体任务进度;同时 ProgressChanged 事件中你用了 += 累加进度值,即使百分比正确,累加操作也会导致进度条值很快超过最大值触发异常。
  • 你后续把整个业务逻辑用 Invoke 包裹到 UI 线程执行,完全失去了 BackgroundWorker 后台线程处理的意义,同时还会导致线程调度冲突,进一步触发异常。
  • 如果没有显式将 backgroundWorker1.WorkerReportsProgress 属性设置为 true,调用 ReportProgress 方法会直接抛出异常。

修复方案

步骤1:调整业务逻辑

预先统计所有待处理文件的总行数作为计算整体进度的分母,上报进度时将已处理行数换算为0~100的合法百分比,移除错误的Invoke包裹逻辑。

步骤2:替换代码

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    string terms;
    StringBuilder sb = new StringBuilder();
    int totalProcessed = 0;
    int totalLines = 0;

    if (string.IsNullOrEmpty(filePath))
        return;
    
    string[] fpath = filePath.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
    
    // 预统计所有文件的总行数
    foreach (string path in fpath)
    {
        if (!string.IsNullOrEmpty(path) && File.Exists(path))
        {
            totalLines += File.ReadAllLines(path).Length;
        }
    }

    // 逐行处理并上报进度
    foreach (string path in fpath)
    {
        if (string.IsNullOrEmpty(path) || !File.Exists(path))
            continue;
                     
        string[] lines = File.ReadAllLines(path);
        for (int i = 0; i < lines.Length; i++)
        {
            terms = lines[i];
            if (terms.Contains("Content to look for"))
            {
                sb.AppendLine(lines[i]);                                
            }
            totalProcessed++;
            // 换算为0~100的合法百分比
            int progress = totalLines == 0 ? 0 : (int)((double)totalProcessed / totalLines * 100);
            backgroundWorker1.ReportProgress(progress);
        }
    }
    // 处理结果可存入e.Result,在RunWorkerCompleted事件中读取
    e.Result = sb.ToString();
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    // 直接赋值不要累加
    progressBar1.Value = e.ProgressPercentage;
    lblPercent.Text = $"{e.ProgressPercentage} %";
}

步骤3:开启进度上报配置

初始化backgroundWorker1时显式开启进度上报权限:

backgroundWorker1.WorkerReportsProgress = true;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 14:45:03