如何处理AccessViolationException

Jer*_*emy 170 .net c# com modi exception

我在我的.net应用程序中使用COM对象(MODI).我调用的方法抛出一个System.AccessViolationException,它被Visual Studio拦截.奇怪的是我在try catch中包含了我的调用,它包含AccessViolationException,COMException和其他所有东西的处理程序,但是当Visual Studio(2010)拦截AccessViolationException时,调试器会中断方法调用(doc.OCR),如果我单步执行,它将继续到下一行,而不是进入catch块.另外,如果我在visual studio外部运行,我的应用程序崩溃了.如何处理COM对象中引发的此异常?

MODI.Document doc = new MODI.Document();
try
{
    doc.Create(sFileName);
    try
    {
        doc.OCR(MODI.MiLANGUAGES.miLANG_ENGLISH, false, false);
        sText = doc.Images[0].Layout.Text;
    }
    catch (System.AccessViolationException ex)
    {
        //MODI seems to get access violations for some reason, but is still able to return the OCR text.
        sText = doc.Images[0].Layout.Text;
    }
    catch (System.Runtime.InteropServices.COMException ex)
    {
        //if no text exists, the engine throws an exception.
        sText = "";
    }
    catch
    {
        sText = "";
    }

    if (sText != null)
    {
        sText = sText.Trim();
    }
}
finally
{
    doc.Close(false);

    //Cleanup routine, this is how we are able to delete files used by MODI.
    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(doc);
    doc = null;
    GC.WaitForPendingFinalizers();
    GC.Collect();
    GC.WaitForPendingFinalizers();

}
Run Code Online (Sandbox Code Playgroud)

vil*_*der 284

在.NET 4.0中,运行时将作为Windows结构化错误处理(SEH)错误引发的某些异常处理为损坏状态的指示符.您的标准托管代码不允许捕获这些损坏的状态异常(CSE).我不会深入了解为什么或如何在这里.阅读本文关于.NET 4.0 Framework中的CSE:

http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035

但是有希望.有几种方法可以解决这个问题:

  1. 重新编译为.NET 3.5程序集并在.NET 4.0中运行它.

  2. 在配置/运行时元素下的应用程序配置文件中添加一行: <legacyCorruptedStateExceptionsPolicy enabled="true|false"/>

  3. 使用HandleProcessCorruptedStateExceptions属性装饰要捕获这些异常的方法.有关详细信息,请参阅http://msdn.microsoft.com/en-us/magazine/dd419661.aspx#id0070035.


编辑

之前,我引用了一篇论坛帖子以获取更多详细信息.但是,由于Microsoft Connect已经退役,如果您有兴趣,可以在此处获取更多详细信息:

来自Microsoft CLR团队的开发人员Gaurav Khanna

由于CLR 4.0的一个名为Corrupted State Exceptions的功能,此行为是设计使然.简单地说,托管代码不应该尝试捕获指示损坏的进程状态的异常,AV就是其中之一.

然后他继续引用HandleProcessCorruptedStateExceptionsAttribute和上面文章的文档.可以说,如果您正在考虑捕获这些类型的异常,那么它绝对值得一读.

  • HandleProcessCorruptedStateExceptions可以解决问题. (49认同)
  • !要注意:强烈建议在AccessViolationException之后结束进程,这是一个损坏的状态异常(CSE).否则会导致更严重的错误. (19认同)
  • `HandleProcessCorruptedStateExceptions`适用于.Net 4.5. (9认同)
  • 谢谢,这真的很有帮助,虽然起初我得到的印象是我需要做**所有3个步骤**才能捕获这些异常,而它实际上是一个"逻辑"OR"的方法来做到这一点.:) (6认同)
  • 谢谢villecoder,您是一颗宝石!我已经处理了好几个星期,试图解决根本问题,最后辞职去治疗症状。您的解决方案是完美的。 (2认同)

小智 14

在配置文件中添加以下内容,它将在try catch块中捕获.谨慎......尽量避免这种情况,因为这意味着发生了某种违规行为.

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)

  • 对于那些使用c++/cli作为dll的人,应该将代码添加到最上面的.exe项目中。 (2认同)

Evi*_*ide 7

从上面的答案编译,为我工作,做了以下步骤来抓住它.

步骤#1 - 将以下代码段添加到配置文件

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>
Run Code Online (Sandbox Code Playgroud)

第2步

添加 -

[HandleProcessCorruptedStateExceptions]

[SecurityCritical]
Run Code Online (Sandbox Code Playgroud)

在你正在追逐的功能的顶部抓住异常

来源:http://www.gisremotesensing.com/2017/03/catch-exception-attempted-to-read-or.html