Question

Quelqu'un pourrait-il créer un court échantillon qui casse, à moins que le [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] est appliqué?

Je viens couru à travers cette sur MSDN et je suis incapable de obtenir à briser, même si je commente sur l'attribut ReliabilityContract. semble enfin s'appelle toujours.

Était-ce utile?

La solution

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

Quand MyFn est jitted, il tente de créer un ConstrainedRegion du bloc finally.

  • Dans le cas sans ReliabilityContract, pourrait être formé sans ConstrainedRegion appropriée, de sorte qu'un code régulier est émis. L'exception de débordement de pile est jeté sur l'appel à Stackoverflow (après le bloc d'essai est exécuté).

  • Dans le cas de la ReliabilityContract, un ConstrainedRegion pourrait être formé et les exigences de la pile de méthodes dans le bloc finalement pourrait être levée en MyFn. L'exception de débordement de pile est maintenant jeté sur l'appel à MyFn (avant que le bloc d'essai est toujours exécuté).

Autres conseils

Le principal moteur de cette fonctionnalité était en charge les serveurs SQL exigences strictes pour l'intégration du CLR dans SQL Server 2005. Probablement pour que d'autres pourraient utiliser et probablement pour des raisons juridiques cette intégration profonde a été publié sous la forme d'une API d'hébergement, mais les exigences techniques ont été Serveurs SQL. Rappelez-vous que dans SQL Server, MTBF est mesurée en mois et non en quelques heures la remise en marche du processus, car une exception non gérée est arrivé est tout à fait inacceptable.

MSDN Magazine article est probablement le meilleur que je l'ai vu décrire les exigences techniques de l'environnement d'exécution limité a été construit pour.

Le ReliabilityContract est utilisé pour décorer vos méthodes pour indiquer comment ils fonctionnent en termes d'exceptions potentiellement asynchrones (ThreadAbortException, OutOfMemoryException, StackOverflowException). Une section région d'exécution limitée est définie comme un cliquet ou enfin (ou erreur) d'un bloc d'essai qui est immédiatement précédé par un appel à 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
}

Lorsqu'une méthode de ReliabilityContract est utilisé à partir d'un CER, il y a 2 choses qui lui arrivent. La méthode sera pré-préparée par le JIT afin qu'il n'invoquera le compilateur JIT la première fois qu'il est exécuté qui pourrait essayer d'utiliser lui-même la mémoire et provoquer ses propres exceptions. Aussi tandis qu'à l'intérieur d'un CER l'exécution promet de ne pas lancer une exception ThreadAbort et attendra de jeter l'exception qu'après la CER terminée.

Pour en revenir à votre question; Je suis encore en train de venir avec un simple exemple de code qui directement répondre à votre question. Comme vous l'avez déjà deviné que, le plus simple échantillon va nécessiter beaucoup de codes étant donné la nature asynchrone du problème et sera probablement du code SQLCLR parce que c'est l'environnement qui utilisera URCE pour le plus grand bénéfice.

Êtes-vous d'exécuter l'exemple MSDN sous le débogueur? Je ne pense pas qu'il soit possible pour les CER de fonctionner lorsque vous exécutez dans le débogueur, comme le débogueur lui-même change la nature de l'exécution de toute façon.

Si vous construisez et exécutez l'application en mode release optimisé, vous devriez être en mesure de voir échouer.

Bien que je n'ai pas un exemple concret pour vous, je pense que vous manquez le point d'avoir un bloc try..finally à l'intérieur des méthodes qui garantissent le succès. Le point entier de dire que la méthode réussira toujours des moyens qui concerne de ce (exception) se produit lors de l'exécution, des mesures seront prises pour assurer que les données seront accessibles dans un état valide lorsque la méthode retourne. Sans le try..finally, vous ne seriez pas assurer quoi que ce soit, et pourrait signifier que seulement la moitié des opérations que vous vouliez arriver, se passerait-il. Ainsi, Cer.Success ne garantit pas réellement le succès, il indique seulement que vous en tant que développeur garantissez le succès.

Consultez cette page pour une explication des différences entre les états et la réussite MayFail en ce qui concerne une méthode Array.CopyTo: http://weblogs.asp.net/justin_rogers/archive/2004/10/05/238275.aspx

attributs CER sont des moyens de documentation. Ils influencent la façon dont CLR exécuter du code dans certaines situations, mais je crois qu'ils (ou leur absence) ne sera jamais entraîner par erreur dans les versions actuelles de .NET.

Ils sont la plupart du temps «réservé à une utilisation future.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top