C#偶发的AccessViolationException

4

我有一个第三方库,有时会导致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;
        }
    }

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

解决方案

非常感谢Theodoros。我已经为上述方法添加了以下属性。现在异常被捕获了。

[System.Runtime.ExceptionServices.HandleProcessCorruptedStateExceptions]
    [System.Security.SecurityCritical]

P.S- 如果有人知道我应该研究什么,我仍然很想了解关于多进程解决方案的内容。再次感谢。

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


2
我假设第三方库是一个非托管的dll,如果它是托管的--就不应该出现AccessViolationException异常。你考虑过向提供者报告崩溃情况,或在那里提交错误报告吗? - Sriram Sakthivel
2
你在使用线程吗?也许你只是以线程不安全的方式使用库,从而导致了崩溃。 - usr
1个回答

5
一个AccessViolationException通常会在进程尝试访问不属于它自己的内存时引发异常。(顺便说一下,NullReferenceException只是在低地址处与不同名称服务的AccessViolationException,以给你一个提示,告诉你什么原因导致了它。)因此,可以合理地说,这更或多或少就是程序内部发生的情况:对无效指针(可能是空指针)的解除引用或访问特定缓冲区边界之外的内容。
如果您没有处理指针,那么您的代码就不会负责产生问题。正在调用的构造函数需要进行一些不安全和无效的操作。如果您使用的库是开源的,您可以进入其中并尝试通过寻找像上述描述的可疑行为来诊断问题。然后,您可以尝试修复它(并可能将您的修复方案贡献给该库的开发人员)。
如果由于任何原因无法执行上述操作,则存在解决方法。默认情况下,托管代码不能捕获AccessViolationException,因为它是一种已损坏的状态异常(CSE),但您可以选择处理此类异常,全局地(通过应用另一个答案中描述的修复方法)或逐个方法(通过使用[HandleProcessCorruptedStateExceptions]属性)。
但是,您必须了解所承担的风险:您的程序将尝试从已损坏的状态中恢复。如果可能,请尽量不要使用强制您这样做的库。

非常感谢您的帮助,这解决了我的问题,现在异常已经被捕获。我已经更新了属性。再次感谢! - Noobie3001

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接