我正在使用Threadpool.QueueUserWorkItem,如下面的
public void TestMain()
{
try
{
ThreadPool.QueueUserWorkItem(x =>
{
this.Dispatcher.BeginInvoke(new Action(() => this.BackGroundMethod()));
}
);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private void BackGroundMethod()
{
try
{
int a = 0;
int b = 100;
var error = b / a;
}
catch(Exception)
{
throw;
}
}
通过这种方式,TestMain()无法捕获异常。 程序将关闭......
我怎样才能发现这个错误?
THX。
答案 0 :(得分:1)
原因是this.Dispatcher.BeginInvoke(new Action(() => this.BackGroundMethod));
异步执行,因此它会在执行TestMain
之前完成执行BackGroundMethod
内的所有代码。
答案 1 :(得分:1)
使用Dispatcher.UnhandledException
事件来捕获TestMain()
方法中的异常,如下所示:
Dispatcher.UnhandledException += (sender, args) => MessageBox.Show(args.Exception.Message);
ThreadPool.QueueUserWorkItem(ignore => Dispatcher.Invoke(new Action(BackGroundMethod)));
编辑:请记住设置Handled
属性以防止调用内部异常处理程序:
Dispatcher.UnhandledException += (sender, args) =>
{
MessageBox.Show(args.Exception.Message);
args.Handled = true;
}
答案 2 :(得分:0)
当您使用Dispatcher创建一个新线程时,该线程拥有它自己的堆栈,因此异常不会传递给TestMain
中的try ... catch,而是它们将来自{{1 }} 方法。当您在BackgroundMethod
中抛出异常时,try catch是无用的,因此如果您不在BackgroundMethod
中抛出异常,则程序将无法关闭。
BackgroundMethod
答案 3 :(得分:0)
您可以通过处理AppDomain.UnhandledException
来捕获应用程序中所有线程中的所有异常答案 4 :(得分:0)
为防止崩溃,请在可能抛出的操作周围添加try
/ catch
:
ThreadPool.QueueUserWorkItem(x =>
{
try {
this.Dispatcher.BeginInvoke(new Action(() => this.BackGroundMethod()));
}
catch (DivideByZeroException ex) {
// handle the error somehow
}
});
但是,请考虑一下您在这里做了什么:您正在向线程池推送一些操作,然后将相同的操作推送到调度程序线程。如果没有QueueUserWorkItem
电话,为什么不直接自己做?
答案 5 :(得分:0)
您可以通过捕获BeginInvoke函数中的异常并将其保存在临时变量中来完成此操作。在等待之后,您可以在正确的线程上重新抛出它。
Exception thrown = null;
await Application.Current.Dispatcher.BeginInvoke(new Action<Action>(x =>
{
try
{
BackGroundMethod();
}
catch (Exception ex)
{
//exceptions on this thread MUST be caught or the program will exit
//we will save it, and then when we are back on the main thread we will rethrow it
thrown = ex;
}
}));
if (thrown != null)
throw thrown; //<--- I'm rethrowing it right here on the correct thread