捕获在不同线程中引起的异常
本文关键字:异常 线程 | 更新日期: 2023-09-27 18:19:46
下面的例子简化了我的问题。在新线程中引发异常。如果我没有在线程中处理这个问题,它就不会被外部try/catch捕获,并使我的应用程序崩溃。
有什么方法可以保证我捕捉到发生的任何异常吗。
try
{
new Thread(delegate()
{
throw new Exception("Bleh"); // <--- This is not caught
}).Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
一般来说,在线程本身中捕获异常是最容易的。
但是,如果您想从线程函数本身单独捕获异常(并且如果您可以使用Task
而不是旧的Thread
方法),您可以编写这样的代码:
var task = Task.Factory.StartNew(() =>
{
throw new Exception("Test");
});
task.ContinueWith(t => handleException(t.Exception), TaskContinuationOptions.OnlyOnFaulted);
这使用ContinueWith()
在第一个线程完成并发生异常后调用另一个方法,因此您可以记录异常或其他内容:
static void handleException(AggregateException exception)
{
foreach (var ex in exception.Flatten().InnerExceptions)
Console.WriteLine(ex.Message);
}
这并不能真正让你修复任何事情——唯一明智的方法是在线程函数本身中正确处理异常。
我这样说,我相信这是最安全的:
var thread = new Thread(MyMethod);
thread.start();
这就是方法。try-catch应该在任何线程方法中
private void MyMethod()
{
try
{
{
throw new Exception("Bleh");//<--- This's not caught => now it is caught :)
}
}
catch (Exception ex)
{
Logger.Log(ex.ToString());
}
}
使用AppDomain.UnhandledException、Application.ThreadException或Dispatcher.UnhandledException。这取决于应用程序的实际类型。
另一种可能性是使用AOP(脑海中浮现出PostSharp)。然而,捕捉异常并不是唯一的目标。您需要找到一种方法来修复异常的原因。如果它是一个bug,那么异常是有帮助的,并且日志记录就足够了。如果有更复杂的原因,你需要思考并采取对策。不幸的是,没有"通用的解决方案"。所以,如果你事先没有发现异常情况,我怀疑你是否能很好地采取行动。
根据我的理解,.Net不允许在两个线程之间进行通信。Beacause线程彼此隔离。你可以用一种简单的方式做到这一点,我不知道它对你有多合适。如果答案有用,请把它标记出来。
public Exception exception;
private void button1_Click(object sender, EventArgs e)
{
try
{
new Thread(delegate()
{
try
{
throw new Exception("Bleh"); // <--- This is not caught
}
catch (Exception e)
{
exception = e;
}
}).Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
if (exception != null)
{
//your code here
}
}