我通过反射调用一种可能导致异常的方法.如何在没有包装器反射的情况下将异常传递给调用者?
我正在重新抛出InnerException,但这会破坏堆栈跟踪.
示例代码:
public void test1()
{
// Throw an exception for testing purposes
throw new ArgumentException("test1");
}
void test2()
{
try
{
MethodInfo mi = typeof(Program).GetMethod("test1");
mi.Invoke(this, null);
}
catch (TargetInvocationException tiex)
{
// Throw the new exception
throw tiex.InnerException;
}
}
Run Code Online (Sandbox Code Playgroud) 有什么区别
try { ... }
catch{ throw }
Run Code Online (Sandbox Code Playgroud)
和
try{ ... }
catch(Exception e) {throw new Exception(e.message) }
Run Code Online (Sandbox Code Playgroud)
无论第二个显示消息?
我知道一开始这似乎是不可能的,一开始对我来说也是如此,但最近我看到了这种代码抛出 a NullReferenceException,所以这绝对是可能的。
不幸的是,Google 上几乎没有任何结果可以解释诸如此类的代码何时foo == null会引发 NRE,这会使调试和理解其发生的原因变得困难。因此,为了记录这种看似奇怪的事件可能发生的可能方式。
这段代码可以以什么方式foo == null抛出NullReferenceException?
在我们的ASP .net网站上,我一直在异常的堆栈跟踪中得到错误的行号.我在谈论我们的现场环境.似乎有一种模式:堆栈跟踪将始终指向包含方法的右大括号的行.
例如:
public class Foo
{
public void Bar()
{
object someObject = null;
someObject.ToString();
/*
arbitrarily more lines of code
*/
} // this line will be the one that the stack trace points to
}
Run Code Online (Sandbox Code Playgroud)
需要明确的是:这不仅适用于某些方法,而是发生在我们记录的每个异常中.所以我会在这里排除(JIT)优化,这可能会导致行号看似随机关闭.困扰我的是,错误的行号似乎始终指向包含方法的右大括号.
请注意,在.net 4.6之前,框架中确实存在一个错误,如果您编译了目标x64,那么确实会发生这种情况.但是,微软证实这已得到修复.同时运行一个最小的示例应用程序,重申他们的主张.但由于某种原因,它仍然发生在Web服务器上.
令我更困惑的是,它在我们的测试和开发环境中不会发生.测试和实时系统设置非常相似.唯一真正的区别是我们正在运行Windows Server 2012,而在测试系统上我们仍在使用Windows Server 2008.
解决这个问题的任何线索都受到高度赞赏.如果您知道我们可以查询的任何内容,请告诉我们.
与一位同事进行了一场激烈的辩论,讨论他在try/catch中包装他的大部分功能的做法,但是抓住它只是一个"抛出",例如
Private sub foo()
try
'Do something'
catch
throw 'And nothing else!'
End Try
End Sub
Run Code Online (Sandbox Code Playgroud)
我的想法是甚至不打扰(假设你此时不需要做任何事情) - 异常会冒泡到父成员中的下一个异常处理程序.
听起来似乎有道理的唯一论点是,有时异常没有被捕获并且您的代码停止了(在调试模式下),当前行以绿色突出显示...并且这可能与多个线程有关?最佳实践会声明"每个线程的异常处理程序",但大多数情况下我们使用单线程.
好处可能是它在调试模式下可能有用而不会突然弹出到父成员(是的,Joel!) - 你将转到"throw"语句并能够检查你的本地人.但是那么你的代码将"乱七八糟地尝试/捕获/抛出"(在这里引用另一个线程)?
如果没有异常发生,那么在任何地方添加try/catch/throws会涉及什么样的开销(即你应该避免在紧密循环中尝试/捕获)?
您显然能够在不丢弃.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日志行.它没有任何区别,堆栈跟踪总是包含错误的行号,使其不太有用.
它为什么这样做?我该怎么做?
我注意到 VS 中的调用堆栈似乎总是偏离一行。一旦我进入一个函数,我刚刚离开的堆栈帧的行号就会增加并指向下一个非空行。然后,如果我双击“调用堆栈”窗口中的该框架,它确实会将我带到我实际所在的函数调用之后的某行。我已在 VS2015 和 VS2017 的空项目中重新存储了此内容(调试版本)。
在下图中,您会注意到第二个堆栈帧指示第 17 行,这是调试器实际停止的 Log() 调用下方几行的返回。
这是一个微不足道的重现,但我在实际项目中经常看到这种情况,并且我不记得在过去几天之外遇到过这个问题。
任何人都知道可能是什么原因造成的?
我正在尝试修复一个我无法重现的错误(yipeee!).我有最初发现问题的用户复制的堆栈跟踪,它显示了在检查对象为null的行上抛出空引用异常(未处理)的代码.如下所示:
private void someFunction()
{
radioButton1.CheckedChanged -= checkedChangedEventHandler
radioButton2.CheckedChanged -= checkedChangedEventHandler
if (someObject != null) // throws NullReferenceException...allegedly
{
if (someObject.Property == something)
{
// set properties on some UI components
}
}
}
Run Code Online (Sandbox Code Playgroud)
什么样的条件会导致这种情况?
UPDATE
添加了一些代码.SomeCunction方法由checkedChanged事件处理程序调用.
更新2
堆栈跟踪必须是错误的,因为你们有几个人建议.没有运算符重载,并且该方法仅引用四个非UI组件的对象(标签和单选按钮),并且所有这些对象在初始化时仅分配一次,并且在获取此代码之前被多次引用,因此任何在此之前,空引用会被捕获.我将不得不更仔细地查看调用事件处理函数.
这是一个解释具有错误行号的堆栈跟踪的线程: