在非UI线程上抛出exception时,如何保留堆栈跟踪
这样做是不好的forms,因为它不保留堆栈跟踪:
try { /*... some code that can throw an exception ...*/ } catch (Exception e) { throw e; // ...Use "throw;" by itself instead }
但是,如果exception是在非UI线程上捕获的,我想将其重新提升回UI并处理它,以便用户获取如下消息:
try { /*... some code that can throw an exception ...*/ } catch (Exception e) { Dispatcher.Invoke((Action)(() => { throw; })); }
但是,我不能在这里单独使用throw关键字,因为C#lexer(正确)认为throw语句不在catch中 。 我必须这样做:
try { /*... some code that can throw an exception ...*/ } catch (Exception e) { Dispatcher.Invoke((Action)(() => { throw e; })); }
并重新抛出exception,这会丢失其堆栈跟踪。
是否有任何(简单)方法来解决这个问题(我总是可以在exception准备好切换线程时打包堆栈跟踪,但这看起来很糟糕)?
注意:我看到了这个post,但它只在标题中类似,而不是内容。
通常的方法是抛出一个新的exception,原始包含在InnerException
。 Exception
有一个特殊的构造函数 。
但是如果你真的想要这样做并且你在.Net 4.5上, 你可以使用ExceptionDispatchInfo
来捕获ExceptionDispatchInfo
的堆栈跟踪,然后在不重置堆栈跟踪的情况下将其重新抛出到其他地方。 但在大多数情况下,使用旧方法将exception包装在新方法中可能更好。