任何人都可以创建一个 短样本 打破,除非 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 被申请;被应用?

我刚刚经历过这个 MSDN 上的示例 即使我注释掉 ReliabilityContract 属性,也无法将其破坏。最后似乎总是被叫到。

有帮助吗?

解决方案

using System;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;

class Program {
    static bool cerWorked;

    static void Main( string[] args ) {
        try {
            cerWorked = true;
            MyFn();
        }
        catch( OutOfMemoryException ) {
            Console.WriteLine( cerWorked );
        }
        Console.ReadLine();
    }

    unsafe struct Big {
        public fixed byte Bytes[int.MaxValue];
    }

    //results depends on the existance of this attribute
    [ReliabilityContract( Consistency.WillNotCorruptState, Cer.Success )] 
    unsafe static void StackOverflow() {
        Big big;
        big.Bytes[ int.MaxValue - 1 ] = 1;
    }

    static void MyFn() {
        RuntimeHelpers.PrepareConstrainedRegions();
        try {
            cerWorked = false;
        }
        finally {
            StackOverflow();
        }
    }
}

当MyFn是jitted,它试图创建一个ConstrainedRegion从最后块。

  • 在这种情况下不ReliabilityContract,没有适当的ConstrainedRegion可能是形成,这样一个规则的代码是发射。堆溢出的例外是扔在叫到计算器(后试图块的执行)。

  • 在这种情况ReliabilityContract,ConstrainedRegion可能是形成堆的要求的方法在最后块可以提升到MyFn.堆溢出的例外是现在扔在呼吁MyFn(前的尝试块曾经执行)。

其他提示

此功能的主要驱动力是为了支持SQL服务器的严格要求为CLR集成到SQL Server 2005的可能,以便其他人可以使用,可能这个深度整合已作为一个托管API,但技术要求是合法的理由SQL服务器。请记住,在SQL Server,MTBF以月不小时,并且过程重新开始测量,因为未处理的异常发生完全不能接受的。

MSDN杂志文章可能是我见过的描述的技术要求约束的执行环境是为建立最好的之一。

在ReliabilityContract被用来装饰你的方法,以指示它们在潜在异步异常的术语(ThreadAbortException,OutOfMemoryException异常,StackOverflowException)如何操作。受约束的执行区域被定义为catch或最后(或故障)try块,其立即被调用之前到System.Runtime.CompilerServices.RuntimeServices.PrepareConstrainedRegions的部分()。

System.Runtime.CompilerServices.RuntimeServices.PrepareConstrainedRegions();
try 
{
    // this is not constrained
} 
catch (Exception e) 
{
    // this IS a CER
} 
finally 
{
    // this IS ALSO a CER
}

当一个ReliabilityContract方法是从CER内使用,有2件事情发生给它。该方法将由JIT事先准备好的,这样就不会调用JIT编译器第一次它的执行可能尝试使用内存本身的原因,而是自己的异常。也同时CER的内部运行时保证不会抛出一个异常ThreadAbort,将等待抛出异常,直到CER完成后。

所以,回到你的问题;我仍然试图拿出,将直接回答你的问题一个简单的代码示例。正如你可能已经虽然猜到了,最简单的样品将需要相当多的代码中给出的问题的异步性,并很可能会SQLCLR代码,因为这是将使用最受益的CER环境。

您运行调试器下的MSDN样?我不认为这是可能的CER来当你在调试器中执行功能,如调试器本身无论如何改变执行的性质。

如果你建立和运行优化的释放模式的应用程序,你应该能够看到它失败。

虽然我没有给你一个具体的例子,但我认为你错过了 try..finally 阻止保证成功的方法的要点。说该方法总是成功的全部意义在于,无论执行期间发生什么(异常),都将采取措施确保方法返回时所访问的数据处于有效状态。如果没有 try..finally,您将无法确保任何事情,并且可能意味着您想要发生的操作只有一半会发生。因此,Cer.Success 实际上并不保证成功,它只是表明您作为开发人员保证成功。

查看此页面,了解与 Array.CopyTo 方法相关的 Success 和 MayFail 状态之间的差异的说明: http://weblogs.asp.net/justin_rogers/archive/2004/10/05/238275.aspx

CER属性是文档的装置。他们这样做影响如何CLR会在某些情况下执行代码,但是我相信他们(或缺乏他们)将永远不会导致错误在.NET的最新版本。

它们大多'保留为将来使用。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top