您显然能够重新抛出异常,而不会丢弃.NET中的堆栈跟踪。
然而它似乎没有起作用。
我遵循的基本用法是:
[WebMethod]
public void ExceptionTest()
{
try
{
throw new Exception("An Error Happened");
}
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
throw;
}
}
问题是,throw;
行的行中的行号,而不是原始的throw new
行。
我在一个简单的exe项目中测试过,没有登录到Windows日志行。它没有任何区别,堆栈跟踪总是包含错误的行号,使其不太有用。
为什么这样做? 我该如何正确地做到这一点?
答案 0 :(得分:6)
如果将原始异常置于内部异常中,则不会丢失原始异常。
[WebMethod]
public void ExceptionTest()
{
try
{
throw new Exception("An Error Happened");
}
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
throw new Exception("Your message", ex);
}
}
答案 1 :(得分:5)
我已经使用了以下几年了。不知道是否有更少“狡猾”的方式在更新的.Net框架中实现它:
public void PreserveStackTrace(Exception ex)
{
MethodInfo preserve = ex.GetType().GetMethod("InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic);
preserve.Invoke(ex,null);
}
要使用它:
[WebMethod]
public void ExceptionTest()
{
try
{
throw new Exception("An Error Happened");
}
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
PreserveStackTrace(ex);
throw ex;
}
}
更新:根据@ dcastro的评论,我想看4.5中的扩展方法(< 4.5它仍然可以是包含上述方法的扩展名):
public static void ReThrow(this Exception ex)
{
var exInfo = ExceptionDispatchInfo.Capture(ex);
exInfo.Throw();
}
所以你只有:
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
ex.ReThrow();
}