【问题标题】:System.Reflection.TargetInvocationException not being caughtSystem.Reflection.TargetInvocationException 未被捕获
【发布时间】:2017-02-18 15:43:43
【问题描述】:

解决方案后添加的注意事项:在反射调用的方法中抛出了 AccessViolationException。这就是无法捕获 TargetInvocationException 的原因。

注意:这在 IDE 之外。 The referenced question is NOT the same.

TL;DR

  1. 无法获取堆栈跟踪
  2. 无法获取内部异常
  3. 无法使用调试器(第三方库的复制保护方案妨碍了)
  4. 对代码的任何更改都会阻止异常发生 - 意味着我无法添加日志记录来找出异常发生的位置

我如何才能捕获异常或以其他方式获取所需信息?

详细说明:

我在通过反射调用的方法中发生异常时遇到问题。异常本身实际上发生在被调用的方法中,但是由于该方法是通过反射调用的,所以真正的异常被包裹在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

【问题讨论】:

  • 不是重复的,因为这发生在 IDE 之外。
  • 这是很多文字,只有很少的信息可以让任何人猜测原因。没有堆栈跟踪。没有代码实际上是您问题的一部分。您提到在线程中运行的东西,但没有说明如何。请附上相关信息。
  • @Alex:这正是问题所在。我无法获得比 System.Reflection.TargetInvocationException 更进一步的堆栈跟踪。我不是在寻求帮助来修复我的代码。我正在寻求帮助以获取可以让我自己修复它的信息。
  • 我在我的 Catch 块内使用 System.Reflection.MethodInfo.GetCurrentMethod.ToString NOT 在它之外它工作得很好......你为什么是 invoking ,反正它什么也没做...

标签: .net vb.net reflection


【解决方案1】:

找到了我无法捕获异常的原因:

实际的异常是 AccessViolationException,如果不采取特殊步骤,则无法在 dotnet 4.0 中捕获 (How to handle AccessViolationException.)

为了让事情更有趣,当通过反射调用的方法中抛出 AccessViolationException 时,Windows 事件日志中只会记录一个 TargetInvocationException,并且转储中只有 TargetInvocationException 可用。

一旦我设法得到真正的异常,我发现它是从非 GUI 线程调用 Application.DoEvents() 导致 AccessViolation。当在 GUI 线程 (Use of Application.DoEvents()) 上调用时,DoEvents() 可以带来足够的乐趣,更不用说从后台线程调用时了。

修复后,我发现我们的第三方库(具有复制保护的库)不喜欢在不同的实例中同时被调用。解决这个问题需要在正确的位置使用同步锁。

导致所有这些乐趣的代码曾经都在 GUI 线程中,最初是在 dotnet 1.1 时代写回的——这解释了对 DoEvents 的调用。代码已被分段转换为通过多个不同阶段在后台线程中并行运行,没有一个开发人员对整个过程有完整的了解。

【讨论】:

  • 你是怎么调试这个的?我们在 Windows 事件日志中看到了相同的问题,只是 TIE 结束了
  • 添加 Try/catch(如果您还没有)然后按照此处的说明 (stackoverflow.com/a/4759831/3945058) 启用捕获“损坏状态”异常。
  • 嗨,这似乎是my problem too,我注意到我的异常发生后Windows 错误报告日志中的AccessViolationException。有一件事并不完全清楚,如果你能澄清它:你的异常是否真的发生在堆栈跟踪所示的点,或者它是否发生在一些完全不同的线程上并且只出现在你的方法内部失败?您是如何设法获得“真正的例外”的?
  • @Lousy:我终于设法按照我在这个答案中链接到的答案中的说明以及我对这个答案的第一条评论中的说明来捕获异常。在你的 app.config 中有一个指令告诉 .Net 让你捕获所有异常。然后,您可以捕获并记录异常,包括堆栈跟踪。
  • app.config 设置就是您所需要的。而且,是的,TargetInvocationException 是一个红鲱鱼。它被记录在 Windows 事件日志中,但真正的问题完全是另外一回事。 TargetInvocationException 仅告诉您在 Invoked 方法中发生了错误,但它不是错误本身。
【解决方案2】:

我不确定我是否可以复制您的问题,但这就是我们得到它的方式,它工作得很好......

 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

让我知道你的效果如何?

【讨论】:

  • 正如我所说,catch 没有捕获任何东西,程序只是崩溃了。我得到的只是一个 Windows 事件日志条目,它说程序崩溃并告诉我它是什么类型的异常。
  • 那么这是一种不同类型的异常,这就是它没有被捕获的原因...显示该块中的代码...
  • 不能,它有几百行长,并且包括对其他方法的调用。我没有犯下但不得不忍受的古老罪恶。它也绝对是 System.Reflection.TargetInvocationException,但它是由反射方法内部的某些东西引起的。无论如何,类型无关紧要 - Catch ex as Exception 应该捕获所有类型的异常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多