关于c#:如何处理AccessViolationException

How to handle AccessViolationException

我正在.NET应用程序中使用COM对象(modi)。我调用的方法引发System.AccessViolationException,它被Visual Studio拦截。奇怪的是,我已将调用包装在一个try catch中,该catch具有accessViolationException、comException等处理程序,但当Visual Studio(2010)截获accessViolationException时,调试器将中断方法调用(doc.ocr),如果我单步执行,它将继续执行下一行,而不是输入catch b。锁。此外,如果在Visual Studio外部运行此程序,则应用程序将崩溃。如何处理在COM对象中引发的异常?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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();

}


在.NET 4.0中,运行时处理某些异常,这些异常作为Windows结构化错误处理(SEH)错误引发,作为损坏状态的指示器。标准托管代码不允许捕获这些损坏状态异常(CSE)。我不想知道为什么会这样,怎么会这样。阅读本文了解.NET 4.0框架中的CSE:

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

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

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

  • 在configuration/runtime元素下的应用程序配置文件中添加一行:

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

  • 编辑

    之前,我参考了一篇论坛文章了解更多细节。但由于Microsoft Connect已退役,以下是您感兴趣的其他详细信息:

    来自Gaurav Khanna,微软CLR团队的开发人员

    This behaviour is by design due to a feature of CLR 4.0 called Corrupted State Exceptions. Simply put, managed code shouldnt make an attempt to catch exceptions that indicate corrupted process state and AV is one of them.

    然后,他继续参考有关handleProcessCorruptedStateExceptionsAttribute和上述文章的文档。可以这么说,如果您考虑捕获这些类型的异常,那么绝对值得一读。


    在配置文件中添加以下内容,它将被捕获在try catch块中。注意事项…尽量避免这种情况,因为这意味着某种违规行为正在发生。

    1
    2
    3
    4
    5
    <configuration>
       <runtime>
          <legacyCorruptedStateExceptionsPolicy enabled="true" />
       </runtime>
    </configuration>


    从上面的答案汇编,为我工作,做了以下步骤来捕捉它。

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

    1
    2
    3
    4
    5
    <configuration>
       <runtime>
          <legacyCorruptedStateExceptionsPolicy enabled="true" />
       </runtime>
    </configuration>

    第2步

    添加-

    1
    2
    3
    [HandleProcessCorruptedStateExceptions]

    [SecurityCritical]

    在函数的顶部,您正在绑定捕获异常

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


    您可以尝试使用AppDomain.UnhandledException,看看是否可以捕获它。

    **编辑*

    下面是一些可能有用的更多信息(这是一个很长的阅读)。