在奇怪的情况下抛出AccessViolationException

Mar*_*bec 8 .net c# asp.net iis access-violation

我在c#中待了很长时间,但我从未遇到过这种错误.首先,你是否看到关于这个单个代码块的任何错误(可能是错误的)(除了它的逻辑当然,我知道它总是返回0)?

public static int GetDecimals(MySimpleEnum val)
    {
        int result = 0;
        switch (val)
        {
            case MySimpleEnum.Base:
            case MySimpleEnum.Slow:
            case MySimpleEnum.Normal:
            case MySimpleEnum.Quick:
            case MySimpleEnum.Fastest:
                result = 0;
                break;
        }            
        return result;        
    }
Run Code Online (Sandbox Code Playgroud)

发布项目设置: DEBUG constant = false; TRACE constant = true; 优化Code​​ = true; 输出/高级/调试信息=无;

IIS =版本7.5

此方法具有指定的释放设置会抛出" System.AccessViolationException:尝试读取或写入受保护的内存.这通常表示其他内存已损坏."

这是有趣的部分.这些情况是,它不会抛出此异常:

  1. 在IIS(Express和not-Express)8.5上运行它(不需要项目编辑).
  2. 设置优化代码= false; 和输出/高级/调试信息=假;
  3. 将内部方法包装到try/catch块中(尝试使用catch块中的log4net记录异常 - 空日志)
  4. 用一些不同的代码替换方法的内部.

注意事项:

  • 必须在服务器上使用win调试器捕获异常(没有调用常规的.NET异常处理程序)
  • 应用程序在异常后崩溃.
  • 这个代码块在几个月前正在运行(很长一段时间没有发布).错误开始可能是一些更新.
  • 使用IIS 7.5和一台具有IIS 8.5和IIS Express(VS2012)的计算机进行了测试.结果相同.
  • 我尝试了很多不同的项目设置组合.基本上,如果我没有像第2点那样设置设置,它会在IIS 7.5上抛出异常.
  • 我的工作(和构建)计算机正在运行带有最新更新的Windows 8.1.
  • 代码块位于单独的项目(类库)中.

我知道如何解决这个问题.但我不喜欢关闭问题,而不知道原因.此外,我希望将来避免这种情况.你认为你可以帮助我吗?如果它是一些空引用异常,为什么会发生这种情况?为什么它是特定于调试/发布或特定于IIS版本?

*注2:

最近,我在发布了与缺少DLL的(System.Net.Http.Formatting.dll,System.Web.Http.dll,System.Web.Http.WebHost.dll)的问题.这是因为一些微软的安全更新.也许这是类似的东西.*

编辑1 添加枚举声明的结构.

public enum MySimpleEnum
    {
        Base = 0,
        Slow = 1,
        Normal = 2,
        Quick = 3,
        Fastest = 4
    }
Run Code Online (Sandbox Code Playgroud)

另外,我只是尝试添加[MethodImpl(MethodImplOptions.NoInlining)],但没有帮助.

Sim*_*ing 4

托管代码中出现这些类型的访问冲突错误的情况并不常见。它们来自内存损坏,这可能表明硬件有故障 - 在极少数情况下,这表明 CLR 本身存在错误。

此类错误最可能的原因来自其他地方,例如,如果此代码以某种方式使用本机代码 - 在不安全的上下文中调用本机代码或从本机代码调用。

引用 MSDN AccessViolationException

在完全由可验证托管代码组成的程序中,所有引用要么有效,要么为空,并且访问冲突是不可能的。仅当可验证的托管代码与非托管代码或不安全的托管代码交互时,才会发生 AccessViolationException。

无论如何,您通常需要查看代码中的其他位置以查找损坏内存的错误代码。不幸的是,这是一个很难解决的问题。祝你好运!