您显然能够在不丢弃.NET中的堆栈跟踪的情况下重新抛出异常.
但它似乎没有起作用.
因此我遵循的基本用法是:
[WebMethod]
public void ExceptionTest()
{
try
{
throw new Exception("An Error Happened");
}
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,行中的行中的throw;行号,而不是原始throw new行.
我在一个简单的exe项目中测试了它,没有登录到Windows日志行.它没有任何区别,堆栈跟踪总是包含错误的行号,使其不太有用.
它为什么这样做?我该怎么做?
如果将其置于内部异常中,则不会丢失原始异常.
[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);
}
}
Run Code Online (Sandbox Code Playgroud)
我已经使用以下多年了。但是,不知道是否有更少的“狡猾”方法可以在最新的.Net框架中实现:
public void PreserveStackTrace(Exception ex)
{
MethodInfo preserve = ex.GetType().GetMethod("InternalPreserveStackTrace",
BindingFlags.Instance | BindingFlags.NonPublic);
preserve.Invoke(ex,null);
}
Run Code Online (Sandbox Code Playgroud)
要使用此功能:
[WebMethod]
public void ExceptionTest()
{
try
{
throw new Exception("An Error Happened");
}
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
PreserveStackTrace(ex);
throw ex;
}
}
Run Code Online (Sandbox Code Playgroud)
更新:基于@dcastro的评论,我想在4.5中使用扩展方法(在<4.5中,它仍然可以是包装上述方法的扩展):
public static void ReThrow(this Exception ex)
{
var exInfo = ExceptionDispatchInfo.Capture(ex);
exInfo.Throw();
}
Run Code Online (Sandbox Code Playgroud)
因此,您将拥有:
catch (Exception ex)
{
evlWebServiceLog.WriteEntry(ex.ToString(), EventLogEntryType.Error);
ex.ReThrow();
}
Run Code Online (Sandbox Code Playgroud)