小编典典

如何处理 AccessViolationException

all

我在我的 .net 应用程序中使用 COM 对象
(MODI)。我正在调用的方法抛出一个System.AccessViolationException,它被 Visual Studio
截获。奇怪的是我已经将我的调用包装在一个 try catch
中,它具有处理程序AccessViolationExceptionCOMException其他所有内容,但是当 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();

}

阅读 59

收藏
2022-06-29

共1个答案

小编典典

编辑 (2021 年 3 月 17 日)

免责声明:这个答案写于 2011 年,引用了原始的 .NET Framework 4.0 实现,而不是 .NET 的开源实现。


在 .NET 4.0 中,运行时将某些异常作为 Windows 结构化错误处理 (SEH)
错误作为损坏状态的指标进行处理。您的标准托管代码不允许捕获这些损坏状态异常 (CSE)。我不会在这里讨论为什么或如何。阅读这篇关于 .NET 4.0 框架中
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 的一项称为损坏状态异常的功能,此行为是设计使然。简而言之,托管代码不应该尝试捕获表明进程状态损坏的异常,而 AV 就是其中之一。

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

2022-06-29