Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# BackgroundWorker中未处理的异常_C#_Exception_Backgroundworker_Unhandled Exception - Fatal编程技术网

C# BackgroundWorker中未处理的异常

C# BackgroundWorker中未处理的异常,c#,exception,backgroundworker,unhandled-exception,C#,Exception,Backgroundworker,Unhandled Exception,我有一个小型WinForms应用程序,它利用BackgroundWorker对象执行长时间运行的操作 后台操作偶尔会引发异常,通常是当有人打开正在重新创建的文件时 无论代码是否从IDE运行.NET都会弹出一个错误对话框,通知用户发生了未处理的异常。使用发行版配置编译代码也不会改变这一点 根据: 如果该操作引发代码无法处理的异常,BackgroundWorker将捕获该异常并将其传递到RunWorkerCompleted事件处理程序,在该处理程序中,该异常将作为System.ComponentMo

我有一个小型WinForms应用程序,它利用BackgroundWorker对象执行长时间运行的操作

后台操作偶尔会引发异常,通常是当有人打开正在重新创建的文件时

无论代码是否从IDE运行.NET都会弹出一个错误对话框,通知用户发生了未处理的异常。使用发行版配置编译代码也不会改变这一点

根据:

如果该操作引发代码无法处理的异常,BackgroundWorker将捕获该异常并将其传递到RunWorkerCompleted事件处理程序,在该处理程序中,该异常将作为System.ComponentModel..::.RunWorkerCompletedEventArgs的错误属性公开。如果在Visual Studio调试器下运行,则调试器将在引发未处理异常的DoWork事件处理程序中的某个点中断

我希望偶尔会抛出这些异常,并希望在RunWorkerCompleted事件中而不是在DoWork中处理它们。我的代码工作正常,错误在RunWorkerCompleted事件中得到了正确处理,但我一辈子都不知道如何阻止.NET错误对话框抱怨“未处理的异常”的发生

难道后台工作人员不应该自动捕捉错误吗?这不是MSDN文档中所说的吗?在仍然允许异常传播到RunWorkerCompletedEventArgs的error属性时,我需要做什么来通知.NET正在处理此错误?

[Edit]

犹大很有道理。我的示例指出了处理错误的细节,但如果在DoWork方法中从未遇到异常,我的代码实际上会导致另一个异常。这个例子还可以,因为我们特别展示了BackgroundWorker的错误处理能力。但是,如果您没有针对null检查error参数,那么这可能是您的问题

[/编辑]

我看不到同样的结果。你能发一点代码吗?这是我的密码

private void Form1_Load(object sender, EventArgs e)
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += new DoWorkEventHandler(worker_DoWork);
    worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
    worker.RunWorkerAsync();
}

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // Will cause another exception if an exception didn't occur.
    // We should be checking to see if e.Error is not "null".
    textBox1.Text = "Error? " + e.Error;
}

void worker_DoWork(object sender, DoWorkEventArgs e)
{
    for (int i = 0; i < 10; i++)
    {
        if (i < 5)
        {
            Thread.Sleep(100);
        }
        else
        {
            throw new Exception("BOOM");
        }   
    }
}
private void Form1\u加载(对象发送方,事件参数e)
{
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=新的doworkereventhandler(worker\u DoWork);
worker.RunWorkerCompleted+=新的RunWorkerCompletedEventHandler(worker\u RunWorkerCompleted);
worker.RunWorkerAsync();
}
void worker\u RunWorkerCompleted(对象发送方,RunWorkerCompletedEventArgs e)
{
//如果未发生异常,将导致另一个异常。
//我们应该检查e.Error是否为“null”。
textBox1.Text=“错误?”+e.错误;
}
无效工作线程(对象发送器,工作线程目标)
{
对于(int i=0;i<10;i++)
{
如果(i<5)
{
睡眠(100);
}
其他的
{
抛出新异常(“BOOM”);
}   
}
}
程序输出:

错误?系统。例外情况:在 BackgroundException.Form1.worker\u DoWork(对象 发送方,DoWorkEventArgs e)在 D:\Workspaces\Sandbox\BackgroundException\BackgroundException\Form1.cs:line 43在 System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e) 在 System.ComponentModel.BackgroundWorker.WorkerThreadStart(对象 (论据)

一篇有趣的文章,看起来和你的问题很相似。它有一个关于处理异常的部分


您所描述的不是BackgroundWorker定义的行为。我怀疑你做错了什么

下面是一个小示例,它证明BackgroundWorker在DoWork中接受异常,并在RunWorkerCompleted中向您提供这些异常:

var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => 
    { 
        throw new InvalidOperationException("oh shiznit!"); 
    };
worker.RunWorkerCompleted += (sender, e) =>
    {
        if(e.Error != null)
        {
            MessageBox.Show("There was an error! " + e.Error.ToString());
        }
    };
worker.RunWorkerAsync();
我的心理调试技能向我揭示了你的问题:你正在访问e.Result,在你的RunWorkerCompleted处理程序中——如果出现e.Error,你必须在不访问e.Result的情况下处理它。例如,以下代码为bad、bad、bad,并将在运行时引发异常:

var worker = new BackgroundWorker();
worker.DoWork += (sender, e) => 
    { 
        throw new InvalidOperationException("oh shiznit!"); 
    };
worker.RunWorkerCompleted += (sender, e) =>
    {
        // OH NOOOOOOOES! Runtime exception, you can't access e.Result if there's an
        // error. You can check for errors using e.Error.
        var result = e.Result; 
    };
worker.RunWorkerAsync();
以下是RunWorkerCompleted事件处理程序的正确实现:

private void RunWorkerCompletedHandler(object sender, RunWorkerCompletedEventArgs e)
{
    if (e.Error == null)
    {
       DoSomethingWith(e.Result); // Access e.Result only if no error occurred.
    }
}
瞧,您将不会收到运行时异常。

我将添加到:

如果该操作引发代码无法处理的异常,BackgroundWorker将捕获该异常并将其传递到RunWorkerCompleted事件处理程序,在该处理程序中,该异常将作为System.ComponentModel..::.RunWorkerCompletedEventArgs的错误属性公开如果在Visual Studio调试器下运行,调试器将在引发未处理异常的DoWork事件处理程序中的某个点中断。

。。。调试器会将异常报告为“~用户代码未处理异常”


解决方案:不要在调试器下运行,它会按预期工作:在e.Error中捕获异常。

这是一个老问题,但我在谷歌搜索相同症状时发现了它。如果其他人因为同样的原因发现它,请发布此消息


Judah的回答是正确的,但这并不是出现“用户代码中未处理的异常”对话框的唯一原因。如果从后台线程上的构造函数内部引发异常,则该异常将立即导致对话框,并且不会传递给RunWorkerCompleted事件。如果您将有问题的代码移到任何构造函数之外(移到任何其他方法),它将按预期工作。

我也遇到了同样的问题,在我通过谷歌搜索找到这个主题之前,我已经在应用这个答案了

嗯,在我看来,答案部分是正确的。我找到了一个更好的答案

调试器正在使工作正常,如果您在“真实世界条件”下运行应用程序,RunWorkerCompleted将按预期处理异常,并且应用程序行为也是预期的


我希望这个答案有帮助。

+1好的一点。我的示例指出了处理错误的细节,但我的代码将