Domanda

Si poteva creare un breve campione che si rompe, a meno che non si applica il [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]?

Ho appena eseguito attraverso questo su MSDN e sono in grado di ottenere la rottura, anche se io commento l'attributo ReliabilityContract. sembra finalmente ottenere sempre chiamato.

È stato utile?

Soluzione

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

Quando si MyFn jitted, si tenta di creare un ConstrainedRegion dal blocco finally.

  • Nel caso senza ReliabilityContract, non ConstrainedRegion corretta potrebbe essere formato, in modo da regolare un codice viene emesso. L'eccezione di overflow dello stack è gettato sulla chiamata a StackOverflow (dopo il blocco try viene eseguito).

  • Nel caso del ReliabilityContract, un ConstrainedRegion potrebbe essere formato e le esigenze pila di metodi nel blocco finally potrebbe essere sollevato in MyFn. L'eccezione di overflow dello stack è ormai gettato sul chiamata a MyFn (prima che il blocco try viene mai eseguita).

Altri suggerimenti

Il driver principale per questa funzionalità è stato quello di supportare SQL Server severi requisiti per l'integrazione CLR in SQL Server 2005. Probabilmente in modo che altri potrebbero utilizzare e probabilmente per motivi legali questa profonda integrazione è stata pubblicata come API di hosting, ma i requisiti tecnici sono stati SQL Server. Ricordate che in SQL Server, MTBF è misurato in ore non mesi e la ripresa processo perché un'eccezione non gestita che è successo è del tutto inaccettabile.

MSDN articolo della rivista è probabilmente il migliore che ho visto che descrive i requisiti tecnici per l'ambiente di esecuzione vincolata è stata costruita per.

Il ReliabilityContract viene utilizzato per decorare i vostri metodi per indicare come funzionano in termini di eccezioni potenzialmente asincrone (ThreadAbortException, OutOfMemoryException, StackOverflowException). Una regione esecuzione vincolato è definito come un fermo o infine (o errore) sezione di un blocco try che è immediatamente preceduta da una chiamata 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
}

Quando un metodo ReliabilityContract viene utilizzato all'interno di un CER, ci sono 2 cose che accadono ad esso. Il metodo verrà pre-preparato dal JIT modo che non invocherà il compilatore JIT la prima volta che viene eseguito che potrebbe tentare di utilizzare memoria stessa e causa è proprie eccezioni. Anche mentre all'interno di una CER il runtime non promette di gettare un'eccezione ThreadAbort e si aspetta di generare l'eccezione fino a dopo il CER ha completato.

Ma torniamo alla tua domanda; Sto ancora cercando di venire con un esempio semplice codice che risponderà direttamente alla tua domanda. Come avrete già intuito, però, il campione più semplice è andare a richiedere un bel po 'di codice, data la natura asincrona del problema e sarà probabilmente il codice SQLCLR perché questo è l'ambiente che utilizzerà CER per il massimo beneficio.

Stai usando il campione di MSDN nel debugger? Non credo sia possibile per CER di funzionare quando si sta eseguendo all'interno del debugger, come il debugger si cambia la natura di esecuzione in ogni caso.

Se si crea e si esegue l'applicazione in modalità di rilascio ottimizzato, si dovrebbe essere in grado di vedere fallire.

Anche se non ho un esempio concreto per te, penso che vi state perdendo il punto di dispone di un blocco try..finally all'interno dei metodi che garantiscono il successo. Il punto di dire che il metodo riesce sempre significa che riguardi di ciò (eccezione) avviene durante l'esecuzione, verranno prese misure per garantire che i dati cui si accede saranno in uno stato valido quando il metodo ritorna. Senza il try..finally, non sarebbe garantire nulla, e potrebbe significare che solo la metà delle operazioni che volevi accadere, sarebbe accaduto. Così, Cer.Success in realtà non garantisce il successo, si afferma soltanto che voi come lo sviluppatore sta garantendo il successo.

Controlla questa pagina per una spiegazione delle differenze tra successo e MayFail stati in quanto riguarda un metodo Array.CopyTo: http://weblogs.asp.net/justin_rogers/archive/2004/10/05/238275.aspx

attributi CER sono mezzi di documentazione. Fanno influenza come CLR eseguire codice in alcune situazioni, ma credo che (o la mancanza di essi) non potrà mai risultare in errore nelle attuali versioni di .NET.

Sono per lo piu 'riservati per uso futuro'.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top