.net - System.Reflection.TargetInvocationException 未被捕获

标签 .net vb.net reflection

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

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

TL;博士

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

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

    详细说明:

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

    最佳答案

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

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

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

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

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

    引起所有这些乐趣的代码曾经全部在 GUI 线程中,并且最初是在 dotnet 1.1 时代写回的 - 这解释了对 DoEvents 的调用。代码已被分段转换为通过几个不同阶段在后台线程中并行运行,没有一个开发人员可以完整地了解该过程。

    关于.net - System.Reflection.TargetInvocationException 未被捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29682162/

    相关文章:

    c# - 使用多线程进行慢速 Ms 互操作

    mysql - VB.NET -> 组合框随机索引

    c# - 检查构造函数是否调用另一个构造函数

    java - 按名称检索注释

    .net - 点网反射: Calling Invoke on MethodInfo With 'out' Parameter from F#

    c# - 如何在 C# 中执行每次迭代延迟 1 分钟的无限循环?

    c++ - 将 cmd 行转换为 int 控制台 C++

    asp.net - 无法获取要构建的 CodeDom dll,程序集不匹配

    .net - 警告 : "Using the iteration variable in a lambda expression may have unexpected results"

    c# - 如何获取 Enumerable.SequenceEqual 的 MethodInfo