System.Reflection.TargetInvocationException 没有被抓住
System.Reflection.TargetInvocationException not being caught
解决方案后添加的注释:在反射调用的方法中抛出 AccessViolationException。这就是无法捕获 TargetInvocationException 的原因。
注意:这是 IDE 的 OUTSIDE。 The referenced question is NOT the same.
TL;DR
- 无法获取堆栈跟踪
- 无法获取内部异常
- 无法使用调试器(第三方库的复制保护方案妨碍)
- 对代码的任何更改都会阻止异常的发生 - 意味着我无法添加日志记录来找出异常发生的位置
如何捕获异常或通过其他方式获取所需信息?
详细说明:
我遇到了一个问题,该异常发生在通过反射调用的方法中。异常本身实际上发生在被调用的方法中,但由于该方法是通过反射调用的,所以真正的异常被包装在 System.Reflection.TargetInvocationException
中。没问题,只需捕获它并获取内部异常 - 除了 System.Reflection.TargetInvocationException
不会被捕获。我的程序崩溃了,我在 Windows 事件日志中得到了一个转储和一个条目。
Windows 事件日志不包含内部异常,转储也不包含。
我无法将调试器附加到程序,因为这样外部库(需要进行反射调用)将不会 运行 - 复制保护,你不知道吗?
如果我将 try/catch 放入有问题的方法中,则不会发生异常 - 这很糟糕。原因不是固定的,只是不再发生了。
如果我将日志记录到有问题的方法中,也会发生同样的效果——异常不会再发生。
我不能使用日志记录,我不能使用调试器,而且在一个我可以捕获异常并记录它的地方,异常没有被捕获。
我正在使用 Visual Studio 2010 和 dotnet 4.0。
要说清楚:当程序在 Visual Studio 之外 运行 时,try/catch 不起作用,而我不能在 运行 之内Visual Studio 在调试器中,因为程序无法到达发生异常的位置。这不在 IDE.
范围内
消除反射不是一种选择(我只针对一种情况尝试过,异常消失了。)
被调用的方法做了很多事情,但将它分解成更小的方法并没有帮助 - 异常就消失了。
异常不会一直发生,只有当我执行特定的步骤序列时才会发生 - 当它发生时,它总是在整个序列中第二次出现。
在我使用的序列中,该方法几乎同时被两个线程调用 - 输入了一组特定的数据,这导致在两台不同的打印机上打印一份报告和另一个文档 - 一个报告和文件到每台打印机。由于生成报告和打印文档可能需要一段时间,因此它们在后台线程上完成,因此用户可以继续工作。
我怀疑线程互相踩着脚趾(正在进行大量文件和数据库操作)但不知道到底发生了什么,我无法修复它。
下面的代码显示了反射调用的简化版本。
对于可能导致 System.Reflection.TargetInvocationException
未被捕获的原因,或者捕获内部异常的替代方法,是否有人有任何建议?
Try
Dim methode As System.Reflection.MethodInfo
methode = GetType(AParticularClass).GetMethod("OneOfManyMethods", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static)
Dim resultobject As Object = methode.Invoke(Nothing, Reflection.BindingFlags.InvokeMethod Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static, Nothing, New Object() {SomeBooleanVariable, SomeStringVariable}, Nothing)
result = DirectCast(resultobject, DataSet)
Catch ex As Exception
'Log the error here.
End Try
我不确定我是否可以复制您的问题,但这就是我们得到它的方式并且它工作得很好...
Try
'YOUR CODE'
Catch ex As Exception
'This is where we grab it from... It needs to be in this block to work...
System.Reflection.MethodInfo.GetCurrentMethod.ToString
End Try
让我知道你的效果如何?
找到异常捕捉不到的原因:
实际的异常是 AccessViolationException,如果不采取特殊步骤就无法在 dotnet 4.0 中捕获它 (How to handle AccessViolationException.)
为了让事情变得更有趣,当在反射调用的方法中抛出 AccessViolationException 时,只有 TargetInvocationException 被记录在 Windows 事件日志中,并且转储中只有 TargetInvocationException 可用。
一旦我设法得到真正的异常,我发现这是从非 GUI 线程调用 Application.DoEvents() 导致的 AccessViolation。在 GUI 线程 (Use of Application.DoEvents()) 上调用时,DoEvents() 会引起足够的乐趣,更不用说从后台线程调用时了。
修复后,我发现我们的第三方库(具有复制保护的库)不喜欢在单独的实例中同时调用。解决这个问题是在正确位置设置同步时钟的问题。
引起所有这些乐趣的代码曾经都在 GUI 线程中,并且最初是在 dotnet 1.1 时代写的——这解释了对 DoEvents 的调用。代码已通过几个不同的阶段在后台线程中分段转换为 运行 并行,没有任何一个开发人员能够完整了解该过程。
解决方案后添加的注释:在反射调用的方法中抛出 AccessViolationException。这就是无法捕获 TargetInvocationException 的原因。
注意:这是 IDE 的 OUTSIDE。 The referenced question is NOT the same.
TL;DR
- 无法获取堆栈跟踪
- 无法获取内部异常
- 无法使用调试器(第三方库的复制保护方案妨碍)
- 对代码的任何更改都会阻止异常的发生 - 意味着我无法添加日志记录来找出异常发生的位置
如何捕获异常或通过其他方式获取所需信息?
详细说明:
我遇到了一个问题,该异常发生在通过反射调用的方法中。异常本身实际上发生在被调用的方法中,但由于该方法是通过反射调用的,所以真正的异常被包装在 System.Reflection.TargetInvocationException
中。没问题,只需捕获它并获取内部异常 - 除了 System.Reflection.TargetInvocationException
不会被捕获。我的程序崩溃了,我在 Windows 事件日志中得到了一个转储和一个条目。
Windows 事件日志不包含内部异常,转储也不包含。 我无法将调试器附加到程序,因为这样外部库(需要进行反射调用)将不会 运行 - 复制保护,你不知道吗? 如果我将 try/catch 放入有问题的方法中,则不会发生异常 - 这很糟糕。原因不是固定的,只是不再发生了。 如果我将日志记录到有问题的方法中,也会发生同样的效果——异常不会再发生。
我不能使用日志记录,我不能使用调试器,而且在一个我可以捕获异常并记录它的地方,异常没有被捕获。
我正在使用 Visual Studio 2010 和 dotnet 4.0。
要说清楚:当程序在 Visual Studio 之外 运行 时,try/catch 不起作用,而我不能在 运行 之内Visual Studio 在调试器中,因为程序无法到达发生异常的位置。这不在 IDE.
范围内消除反射不是一种选择(我只针对一种情况尝试过,异常消失了。)
被调用的方法做了很多事情,但将它分解成更小的方法并没有帮助 - 异常就消失了。
异常不会一直发生,只有当我执行特定的步骤序列时才会发生 - 当它发生时,它总是在整个序列中第二次出现。
在我使用的序列中,该方法几乎同时被两个线程调用 - 输入了一组特定的数据,这导致在两台不同的打印机上打印一份报告和另一个文档 - 一个报告和文件到每台打印机。由于生成报告和打印文档可能需要一段时间,因此它们在后台线程上完成,因此用户可以继续工作。
我怀疑线程互相踩着脚趾(正在进行大量文件和数据库操作)但不知道到底发生了什么,我无法修复它。
下面的代码显示了反射调用的简化版本。
对于可能导致 System.Reflection.TargetInvocationException
未被捕获的原因,或者捕获内部异常的替代方法,是否有人有任何建议?
Try
Dim methode As System.Reflection.MethodInfo
methode = GetType(AParticularClass).GetMethod("OneOfManyMethods", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static)
Dim resultobject As Object = methode.Invoke(Nothing, Reflection.BindingFlags.InvokeMethod Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static, Nothing, New Object() {SomeBooleanVariable, SomeStringVariable}, Nothing)
result = DirectCast(resultobject, DataSet)
Catch ex As Exception
'Log the error here.
End Try
我不确定我是否可以复制您的问题,但这就是我们得到它的方式并且它工作得很好...
Try
'YOUR CODE'
Catch ex As Exception
'This is where we grab it from... It needs to be in this block to work...
System.Reflection.MethodInfo.GetCurrentMethod.ToString
End Try
让我知道你的效果如何?
找到异常捕捉不到的原因:
实际的异常是 AccessViolationException,如果不采取特殊步骤就无法在 dotnet 4.0 中捕获它 (How to handle AccessViolationException.)
为了让事情变得更有趣,当在反射调用的方法中抛出 AccessViolationException 时,只有 TargetInvocationException 被记录在 Windows 事件日志中,并且转储中只有 TargetInvocationException 可用。
一旦我设法得到真正的异常,我发现这是从非 GUI 线程调用 Application.DoEvents() 导致的 AccessViolation。在 GUI 线程 (Use of Application.DoEvents()) 上调用时,DoEvents() 会引起足够的乐趣,更不用说从后台线程调用时了。
修复后,我发现我们的第三方库(具有复制保护的库)不喜欢在单独的实例中同时调用。解决这个问题是在正确位置设置同步时钟的问题。
引起所有这些乐趣的代码曾经都在 GUI 线程中,并且最初是在 dotnet 1.1 时代写的——这解释了对 DoEvents 的调用。代码已通过几个不同的阶段在后台线程中分段转换为 运行 并行,没有任何一个开发人员能够完整了解该过程。