C#偶尔的AccessViolationException

Noo*_*001 3 c#

我有一个第三方库,有时会导致AccessViolationException.我已经标记了罪魁祸首.我真的很喜欢这种方法优雅地失败,这样我的调用代码可以在短时间内再次尝试,但此时,这个异常会导致整个应用程序崩溃.

    public static PlayerModel GetModel(int instanceId)
    {
        try
        {
            // New player model.
            PlayerModel model = new PlayerModel();

            // Fill.
            model._flakyLibrary = new FlakyLibrary(instanceId); // **Sometimes crashes**
            model.instanceId = instanceId;

            // Return the new player model.
            return model;
        }
        catch
        {
            // Try again in a bit - the game is not fully loaded.
            return null;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我有一个想法是启动一个子进程来运行这一点逻辑并且如果需要那么优雅地崩溃 - 我不知道如何做到这一点,更不用说有一个进程返回这种对象(我的自定义PlayerModel )到另一个过程.我已经筋疲力尽地搜索谷歌和Stack Overflow(也许我在问错误的问题?).

非常感谢Theodoros.我已将以下属性添加到上述方法中.现在被抓住了例外.

[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions]
    [System.Security.SecurityCritical]
Run Code Online (Sandbox Code Playgroud)

PS - 如果有人知道我应该研究什么,我仍然着迷于了解多工艺解决方案?非常感谢再次.

另一个编辑:我找到了使用多个进程的解决方案:NamedPipeServerStream.

The*_*kis 5

一种AccessViolationException是当你的进程试图访问内存,这不是自己的通常引发异常.(顺便提一下,a NullReferenceException只是一个AccessViolationException低地址,用不同的名字,给你一个暗示是什么导致它.)因此,有理由说这或多或少是你的程序内发生的事情:取消引用无效指针(可能是空指针)或超出特定缓冲区边界的访问.

如果你没有弄乱指针,你的代码不负责解决问题.您正在调用的构造函数负责执行不安全和无效的操作.如果您使用的库是开源的,您可以通过查找上述可疑行为,自己进入并尝试自行诊断问题.然后,您可以继续尝试修复它(并可能为该库的开发人员提供修复).

如果由于任何原因无法完成上述操作,则有一种解决方法.默认情况下,托管代码无法捕获AccessViolationException,因为它是一个损坏的状态异常(CSE),但您可以选择全局(通过应用另一个答案中描述的修复)或每个方法(通过使用该 [HandleProcessCorruptedStateExceptions]属性)处理此类异常.

但是,您必须了解所承担的风险:您的程序将尝试从损坏的状态恢复.如果可以的话,尽量不要使用强迫你这样做的库.