Frage

Könnte jemand eine kurzen Probe erstellen , die bricht, es sei denn, die [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] angewendet wird?

Ich lief durch diese Probe auf MSDN und bin nicht in der Lage zu bekommen, es zu brechen, auch wenn ich das ReliabilityContract Attribut Kommentar aus. Schließlich scheint immer aufgerufen.

War es hilfreich?

Lösung

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

Wenn MyFn jitted wird, versucht er, eine ConstrainedRegion aus dem finally-Block zu erstellen.

  • Im Fall ohne ReliabilityContract, keine richtige ConstrainedRegion gebildet werden kann, so dass ein regulärer Code ausgegeben wird. Die Stapelüberlaufausnahme auf dem Anruf zu Stackoverflow ausgelöst wird (nach dem Try-Block ausgeführt wird).

  • In dem Fall mit dem ReliabilityContract, ein ConstrainedRegion gebildet werden kann und die Stapelanforderungen von Methoden im finally-Block könnten in MyFn angehoben werden. Die Stapelüberlaufausnahme jetzt auf dem Anruf zu MyFn geworfen wird (vor dem try-Block immer ausgeführt wird).

Andere Tipps

Der Haupttreiber für diese Funktionalität war zu SQL Server Anforderungen für die Integration der CLR in SQL Server 2005. Wahrscheinlich zu unterstützen, so dass andere und wahrscheinlich aus rechtlichen Gründen diese tiefe Integration wurde als Hosting-API veröffentlicht nutzen könnten, aber die technischen Anforderungen waren SQL Server. Denken Sie daran, dass in SQL Server wird MTBF in Monaten gemessen nicht Stunden und der Prozess Neustarten, weil eine nicht behandelte Ausnahme geschah, ist völlig inakzeptabel.

Das MSDN Zeitschriftenartikel ist wahrscheinlich das beste, das ich je gesehen habe beschreibt die technischen Anforderungen der eingeschränkten Ausführungsumgebung für gebaut wurde.

Die ReliabilityContract wird verwendet, um Ihre Methoden zu dekorieren, um anzuzeigen, wie sie in Bezug auf potenziell asynchronen Ausnahmen (Threadabort, OutOfMemoryException, Stackoverflow) betrieben werden. Ein eingeschränkter Ausführungsbereich ist als Rast definiert oder schließlich (oder Fehler) Abschnitt eines Try-Blockes, der unmittelbar durch einen Aufruf System.Runtime.CompilerServices.RuntimeServices.PrepareConstrainedRegions vorangestellt ist ().

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

Wenn eine ReliabilityContract Methode aus einer CER verwendet wird, gibt es zwei Dinge, die um sie geschehen. Das Verfahren wird durch den JIT vorab vorbereitet werden, so dass es nicht der JIT-Compiler das erste Mal aufrufen, wird sie ausgeführt hat, die Speicher selbst verwenden könnte versuchen und seine eigene Ausnahmen verursachen. Auch während im Innern eines CER die Laufzeit verspricht keinen Threadabort Ausnahme zu werfen und warten, bis die Ausnahme zu werfen, bis der CER abgeschlossen.

auf Ihre Frage Also zurück; Ich versuche immer noch mit einem einfachen Beispielcode zu entwickeln, die Ihre Frage direkt beantworten. Wie Sie bereits obwohl vielleicht erraten haben, wird das einfachste Beispiel der asynchrone Natur des Problems gegeben ziemlich vielen Code zu verlangen, und wird wahrscheinlich SQLCLR Code sein, denn das ist die Umgebung, die CERs für den größten Nutzen verwendet wird.

Sind Sie mit der MSDN-Probe unter dem Debugger? Ich glaube nicht, ist es möglich, für CER funktionieren, wenn Sie innerhalb des Debuggers ausgeführt werden, da der Debugger selbst die Art der Ausführung ändert sich trotzdem.

Wenn Sie die App in optimierte Freigabemodus erstellen und ausführen, sollten Sie in der Lage sein, es verkennen.

Während ich nicht ein konkretes Beispiel für Sie, ich glaube, du verpasst den Punkt haben eine try..finally innerhalb der Methoden blockieren, die den Erfolg garantieren. Der ganze Sinn zu sagen, dass das Verfahren immer Mittel gelingen, die hinsichtlich dessen, was (Ausnahme) geschieht während der Ausführung, werden Schritte unternommen werden, um die Daten zu sichern, die in einem gültigen Zustand, wenn die Methode zurückgibt, zugegriffen wird. Ohne die try..finally, würden Sie nicht sein, etwas zu gewährleisten und könnte bedeuten, dass nur die Hälfte der Operationen, die Sie passieren wollten, passieren würde. Somit muss Cer.Success eigentlich nicht den Erfolg garantieren, heißt es nur, dass man als Entwickler Erfolg werden zu gewährleisten.

Diese Seite Schauen Sie sich für eine Erklärung der Unterschiede zwischen Erfolg und MayFail Staaten, wie es zu einem Array.CopyTo Verfahren betrifft: http://weblogs.asp.net/justin_rogers/archive/2004/10/05/238275.aspx

CER Attribute sind Mittel der Dokumentation. Sie haben Einfluss darauf, wie CLR-Code in einigen Situationen ausgeführt wird, aber ich glaube, sie (oder das Fehlen von ihnen) werden niemals in der aktuellen Versionen von .NET zu Fehlern führen.

Sie sind meist 'reserviert für zukünftige Verwendung'.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top