Pregunta

¿Alguien podría crear un muestra corta que se rompe, a menos que el [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] ¿Está aplicado?

Acabo de pasar por esto muestra en MSDN y no puedo lograr que se rompa, incluso si comento el atributo ReliabilityContract.Finalmente parece que siempre lo llaman.

¿Fue útil?

Solución

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();
        }
    }
}

Cuando se compilados JIT MyFn, se trata de crear un ConstrainedRegion del bloque finally.

  • En el caso sin la ReliabilityContract, sin ConstrainedRegion adecuada podría formarse, por lo regular de un código se emite. La excepción de desbordamiento de pila es lanzada en la llamada a Stackoverflow (después de la ejecución del bloque try).

  • En el caso de la ReliabilityContract, un ConstrainedRegion podría formarse y los requisitos de la pila de métodos en la finalmente bloque podría ser levantada en MyFn. La excepción de desbordamiento de pila está tirado en la llamada a MyFn (antes de que el bloque try se ejecuta cada vez).

Otros consejos

El conductor principal de esta funcionalidad era apoyar a los servidores SQL estrictos requisitos para integrar el CLR en SQL Server 2005. Probablemente, para que otros pudieran usar y probablemente por razones legales esta integración profunda se publicó como una API de alojamiento, pero los requisitos técnicos eran Servidores SQL. Recuerde que en SQL Server, MTBF se mide en horas, no meses y la restauración proceso porque una excepción no controlada ocurrió es completamente inaceptable.

MSDN artículo de la revista es probablemente el mejor que he visto que describe los requisitos técnicos del entorno de ejecución restringido fue construido para.

El ReliabilityContract se utiliza para decorar sus métodos para indicar cómo operan en términos de excepciones potencialmente asíncronos (ThreadAbortException, OutOfMemoryException, StackOverflowException). Una región ejecución constreñido se define como una captura o, finalmente, (o fallo) sección de un bloque try que está inmediatamente precedida por una llamada a 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
}

Cuando se utiliza un método ReliabilityContract desde dentro de un CER, hay 2 cosas que suceden a la misma. El método será pre-preparada por el JIT por lo que no va a invocar el compilador JIT la primera vez que se ejecuta lo que podría tratar de usar la memoria misma y causar su propia excepciones. Asimismo, mientras que en el interior de un CER el tiempo de ejecución se compromete a no lanzar una excepción ThreadAbort y esperará a emitir la excepción hasta después de la CER ha completado.

Así que de vuelta a su pregunta; Todavía estoy tratando de llegar a un ejemplo de código simple que responder directamente a su pregunta. Como es posible que ya han adivinado, sin embargo, la muestra más simple va a exigir mucho de código dada la naturaleza asíncrona del problema y es probable que sea de código SQLCLR porque ese es el ambiente que utilizar RCE para el mayor beneficio.

¿Está ejecutando la muestra de MSDN en el depurador? No creo que es posible que los CER a funcionar cuando se está ejecutando dentro del depurador, como el depurador en sí cambia la naturaleza de la ejecución de todas formas.

Si se construye y ejecuta la aplicación en modo de lanzamiento optimizado, usted debe ser capaz de ver fracasar.

Si bien no tengo un ejemplo concreto para ti, creo que se está perdiendo el punto de tener un bloque try..finally dentro de los métodos que garantizan el éxito. El punto de decir que el método siempre tendrá éxito medios que respecta de lo que (excepción) que ocurre durante la ejecución, se tomarán medidas para asegurar que los datos sean accedidos estarán en un estado válido cuando el método devuelve. Sin la try..finally, que no sería asegurar nada, y podría significar que sólo la mitad de las operaciones que quería pasar, pasaría. Por lo tanto, Cer.Success en realidad no garantiza el éxito, sólo se afirma que como el desarrollador está garantizando el éxito.

Consulte esta página para una explicación de las diferencias entre los estados de éxito y MayFail lo que se refiere a un método Array.CopyTo: http://weblogs.asp.net/justin_rogers/archive/2004/10/05/238275.aspx

atributos CER son medios de documentación. Lo hacen influir en cómo CLR ejecutar código en algunas situaciones, pero creo que (o la falta de ellos) nunca van a dar lugar a errores en las versiones actuales de .NET.

En su mayoría son 'reservados para uso futuro'.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top