以下示例简化了我的问题。在新线程中抛出异常。如果我不在线程中处理它,它不会被外部try / catch捕获并崩溃我的应用程序。
有没有办法保证我能抓住任何发生的异常。
try
{
new Thread(delegate()
{
throw new Exception("Bleh"); // <--- This is not caught
}).Start();
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
答案 0 :(得分:5)
一般来说,最容易捕获线程本身的异常。
但是如果你想从线程函数本身单独捕获异常(如果你可以使用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);
}
这实际上并没有让你解决任何问题 - 唯一明智的做法是在线程函数本身中正确处理异常。
答案 1 :(得分:2)
我这样说,我相信这是最安全的:
var thread = new Thread(MyMethod);
thread.start();
这个方法。 try-catch应该在任何thread-method
中 private void MyMethod()
{
try
{
{
throw new Exception("Bleh");//<--- This's not caught => now it is caught :)
}
}
catch (Exception ex)
{
Logger.Log(ex.ToString());
}
}
答案 2 :(得分:1)
使用AppDomain.UnhandledException,Application.ThreadException或Dispatcher.UnhandledException。这取决于实际的应用类型。
另一种可能性是使用AOP(PostSharp会想到)。但是,捕获异常并不是唯一的目标。您需要找到一种方法来解决异常的原因。如果它是一个错误,该异常是有用的,并且记录足够。如果有更复杂的原因,您需要考虑并应用对策。不幸的是,没有“一般解决方案”。所以如果你事先没有抓住异常,我怀疑你可以做得很好。
答案 3 :(得分:0)
据我所知,.Net不允许在两个线程之间进行通信。因为线程彼此隔离。您可以通过简单的方式实现这一点,我不知道它适合您。如果有用,请标记答案。
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
}
}