代码之家  ›  专栏  ›  技术社区  ›  Noobie3001

C#偶然访问冲突异常

c#
  •  4
  • Noobie3001  · 技术社区  · 11 年前

    我有一个第三方库,有时会导致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)返回给另一个进程。我已经用尽了搜索Google和Stack Overflow(也许我问错了问题?)。

    解决方案

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

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

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

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

    1 回复  |  直到 10 年前
        1
  •  5
  •   Community Mohan Dere    8 年前

    AccessViolationException 是一个异常,通常在进程尝试访问非自己的内存时引发。(顺便说一下 NullReferenceException 只是一个 访问冲突异常 因此,可以合理地说,这或多或少是在程序内部发生的:对无效指针(可能是空指针)的解引用,或者对特定缓冲区边界之外的访问。

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

    如果由于任何原因无法完成上述操作,则有一个解决方法。默认情况下,托管代码无法捕获 访问冲突异常 ,因为这是一个损坏状态异常(CSE),但您可以选择全局处理此类异常(通过应用 another answer )或按照方法(通过使用 [HandleProcessCorruptedStateExceptions] 属性)。

    然而,您必须了解所冒的风险:您的程序将尝试从损坏的状态中恢复。如果可以的话,尽量不要使用强制您这样做的库。