-->

代码演示一个约束的执行区域的重要性(Code demonstrating the importanc

2019-06-25 10:44发布

任何人都可以创建,打破,除非很短的样品 [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]被施加?

我只是通过这个跑在MSDN上的样品 ,但无法得到它打破,即使我注释掉ReliabilityContract属性。 最后似乎总是被调用。

Answer 1:

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被实时编译,它试图从finally块创建ConstrainedRegion。

  • 在没有ReliabilityContract的情况下,没有适当的ConstrainedRegion可以形成,所以常规代码被发射。 堆栈溢出异常被抛出的(执行try块之后)#2呼叫。

  • 与ReliabilityContract的情况下,一个ConstrainedRegion可以形成和在最后块的方法堆叠要求,可以提升到MyFn。 堆栈溢出异常,现在扔在调用(是不断执行try块之前)到MyFn。



Answer 2:

此功能的主要驱动力是为了支持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代码,因为这是将使用核证减排量为最有益于环境。



Answer 3:

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

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



Answer 4:

虽然我没有给你一个具体的例子,我觉得你有丢失的那保证成功的方法内try..finally块的点。 整点说,该方法将总是成功的是执行过程中有什么(异常)发生的问候,将采取措施,确保被访问将处于有效状态的方法返回时数据手段。 如果没有try..finally,你不会是确保任何东西,可能意味着只有你希望发生的操作的一半,会发生。 因此,Cer.Success实际上并不保证成功,那只能说你作为开发商都保证成功。

看看这个页面的成功和MayFail状态之间的差别的解释,因为它涉及到一个Array.CopyTo方法: http://weblogs.asp.net/justin_rogers/archive/2004/10/05/238275.aspx



Answer 5:

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

他们大多是“留作将来使用”。



文章来源: Code demonstrating the importance of a Constrained Execution Region