System.Reflection.TargetInvocationException未被捕获

时间:2015-04-16 17:39:23

标签: .net vb.net reflection

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

注意:这是IDE的外部。 The referenced question is NOT the same.

TL; DR

  1. 无法获得堆栈跟踪
  2. 无法获得内部异常
  3. 无法使用调试程序(第三方库的复制保护方案妨碍)
  4. 对代码的任何更改都会阻止异常发生 - 意味着我无法添加日志记录以找出发生异常的位置
  5. 如何通过其他方式获取异常或获取所需信息?

    详细说明:

    我遇到的问题是在一个被反射调用的方法中发生的异常。异常本身实际上发生在被调用的方法中,但由于该方法是通过反射调用的,因此真正的异常包含在System.Reflection.TargetInvocationException中。没问题,只需抓住它并获得内部异常 - 除了System.Reflection.TargetInvocationException没有被抓住。我的程序崩溃了,我在Windows事件日志中得到了转储以及一个条目。

    Windows事件日志不包含内部异常,转储也不包含。 我无法将调试器附加到程序中,因为外部库(需要进入反射调用)不会运行 - 复制保护,你知道吗。 如果我将一个try / catch放入有问题的方法中,则不会发生异常 - 这很糟糕。原因尚未解决,它不会再发生了。 如果我将登录记录到违规方法中,也会发生同样的效果 - 例外情况不再发生。

    我无法使用日志记录,我无法使用调试器,并且在我可以捕获异常并记录异常的地方,异常并没有被捕获。

    我正在使用Visual Studio 2010和dotnet 4.0。

    说清楚:当程序在Visual Studio外部运行时,try / catch不起作用,我无法在调试器中的Visual Studio中运行它,因为程序可以&# 39;达到异常发生的点。这不在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
    

2 个答案:

答案 0 :(得分:8)

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

实际的异常是AccessViolationException,无法采取特殊步骤(How to handle AccessViolationException.

无法在dotnet 4.0中捕获

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

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

一旦修复,我发现我们的第三方库(具有复制保护的库)不希望在不同的实例中同时被调用。修复这是一个在正确的地方合并的问题。

导致所有这些乐趣的代码一次都在GUI-Thread中,并且最初是在dotnet 1.1的时代写回来的 - 这解释了对DoEvents的调用。代码已逐段转换为在后台线程中通过几个不同的阶段并行运行,没有一个开发人员对该过程有完整的概述。

答案 1 :(得分:0)

我不确定我可以复制你的问题,但这就是我们如何得到它并且它的工作正常......

 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

请告诉我它是如何运作的?