C# BackgroundWorker中未处理的异常
我有一个小型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参数,那么这可能是您的问题 [/编辑] 我看不到同样的结果。你能发一点代码吗?这是我的密码C# BackgroundWorker中未处理的异常,c#,exception,backgroundworker,unhandled-exception,C#,Exception,Backgroundworker,Unhandled Exception,我有一个小型WinForms应用程序,它利用BackgroundWorker对象执行长时间运行的操作 后台操作偶尔会引发异常,通常是当有人打开正在重新创建的文件时 无论代码是否从IDE运行.NET都会弹出一个错误对话框,通知用户发生了未处理的异常。使用发行版配置编译代码也不会改变这一点 根据: 如果该操作引发代码无法处理的异常,BackgroundWorker将捕获该异常并将其传递到RunWorkerCompleted事件处理程序,在该处理程序中,该异常将作为System.ComponentMo
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好的一点。我的示例指出了处理错误的细节,但我的代码将