【问题标题】:Why do I get TargetInvocationException with BackgroundWorker.ReportProgress?为什么我会通过 BackgroundWorker.ReportProgress 获得 TargetInvocationException?
【发布时间】:2011-11-22 14:46:51
【问题描述】:

我正在从事一个 C# 项目,我有一个 Backgroundworker 来完成我的“昂贵的工作”。

在我的“DoWork”中,我想通过“backgroundworker.ReportProgress(some int)”报告进度。但是当我的程序调用“backgroundworker.ReportProgress(some int)”时,我得到一个“System.Reflection.TargetInvocationException”。

如何解决我的问题?

private void btnGrap_Click(object sender, EventArgs e)
    {
        //some code
        ListsObject listsObject = new ListsObject(filePaths, enumList);
        progressBar1.Maximum = 100;//count;
        this.bgrndWorkerSearchMatches.RunWorkerAsync(listsObject);
     }

_DoWork:

private void backgroundWorkerSearchMatches_DoWork(object sender, DoWorkEventArgs e)
    {
        for (int i = 0; i < 100; i++)
        {
            bgrndWorkerSearchMatches.ReportProgress(i);
        }
     }

_ProcessChanged:

private void bgrndWorkerSearchMatches_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        //progressBar1.Value = e.ProgressPercentage;
    }

我找到了答案:

我用Visual Studio创建了backgroundworker eventhandler,不知道必须手动设置:

bgrndWorkerSearchMatches.WorkerReportsProgress = true;

【问题讨论】:

  • 您可能希望将调试器设置为中断所有异常。

标签: c# multithreading exception backgroundworker


【解决方案1】:

抛出TargetInvocationException 以包装由最终调用的方法抛出的不同异常。

查看InnerException 了解发生了什么。

【讨论】:

  • 我试过codetry { bgrndWorkerSearchMatches.ReportProgress(count); } catch (System.Reflection.TargetInvocationException tiEx) { throw tiEx.InnerException; code 但我在内部异常之前得到了异常
  • 不要throw InnerException;它将破坏堆栈跟踪。相反,请查看调试器中的 InnerException。
【解决方案2】:

找到答案:

我用 Visual Studio 创建了 backgroundworker 事件处理程序,但不知道我必须手动设置:

bgrndWorkerSearchMatches.WorkerReportsProgress = true;

还是非常感谢大家

【讨论】:

    【解决方案3】:

    你没有说这个 ReportProgress() 实际做了什么,但你需要调用这个命令。

    我猜它会是这样的:

    private void ReportProgress(int percentage)
    {
      this.SetProgressBar(percentage);
    }
    

    然后在设置工作线程的“父”代码中:

    delegate void SetProgressBarCallback(int percentage);
    public void SetProgressBar(int percentage)
            {
                // InvokeRequired required compares the thread ID of the
                // calling thread to the thread ID of the creating thread.
                // If these threads are different, it returns true.
                if (this.progressBar1.InvokeRequired)
                {   
                    SetProgressBarCallback d = new SetProgressBarCallback(SetProgressBar);
                    this.Invoke(d, new object[] { percentage});
                }
                else
                {
                    this.progressBar1.value = precentage;
                }
            }
    

    查看here 以获取使用 WinForms 的示例。

    【讨论】:

    • 如果您需要后台操作报告其进度,您可以调用 ReportProgress 方法引发 ProgressChanged 事件。 msdn.microsoft.com/en-us/library/ka89zff4.aspx
    • 如果您使用它来触发进度条位置的更改,您仍然需要检查并使用带有调用的回调来更新 UI。
    猜你喜欢
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-09
    • 2011-12-09
    • 2019-12-25
    • 1970-01-01
    相关资源
    最近更新 更多