Вопрос по c#, concurrency, .net, cer – Код, демонстрирующий важность области ограниченного исполнения

37

Может ли кто-нибудь создатьshort sample что ломается, если только[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] применены?

Я только что пробежал через этообразец на MSDN и я не могу его сломать, даже если я закомментирую атрибут ReliabilityContract. Наконец-то, кажется, всегда звонят.

Ваш Ответ

5   ответов
3

что CER может функционировать при выполнении в отладчике, так как сам отладчик в любом случае меняет характер выполнения.

Если вы соберете и запустите приложение в режиме оптимизированного выпуска, вы увидите, что оно не работает.

1

я думаю, вы упустили смысл попробовать ... окончательно заблокировать методы, гарантирующие успех. Смысл в том, что метод всегда будет успешным, означает, что в отношении того, что (исключение) происходит во время выполнения, будут предприняты шаги, чтобы гарантировать, что доступ к данным будет в допустимом состоянии, когда метод вернется. Без попытки ... в конце концов, вы бы ничего не обеспечили и могли означать, что произойдет только половина операций, которые вы хотели бы выполнить. Таким образом, Cer.Success на самом деле не гарантирует успех, а только утверждает, что вы, как разработчик, гарантируете успех.

Посетите эту страницу для объяснения различий между состояниями Success и MayFail в том, что касается метода Array.CopyTo:http://weblogs.asp.net/justin_rogers/archive/2004/10/05/238275.aspx

Ссылка не работает.
Чтобы быть немного более точным, CER позволяют разработчикам ПОСТУПИТЬ в возможность написания кода, который может защитить себя от повреждения собственного состояния в исключительных условиях. В CER, защищающем CLR, нет ничего присущего, он просто позволяет писать код, который может защитить себя сам. Грязный секрет в CLR 1.0 / 1.1 было НЕВОЗМОЖНО писать код, который мог бы успешно работать с определенными классами исключений.
CER в основном предназначен для защиты размещенных CLR от повреждения в ходе разрушения домена приложения и других исключительных условий. Такие хосты, как SQL Server, могут вызывать грубые прерывания, во время грубых прерываний, наконец, предложения могут быть прерваны. Sam Saffron
44
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();
        }
    }
}

он пытается создать ConstrainedRegion из блока finally.

In the case without the ReliabilityContract, no proper ConstrainedRegion could be formed, so a regular code is emitted. The stack overflow exception is thrown on the call to Stackoverflow (after the try block is executed).

In the case with the ReliabilityContract, a ConstrainedRegion could be formed and the stack requirements of methods in the finally block could be lifted into MyFn. The stack overflow exception is now thrown on the call to MyFn (before the try block is ever executed).

Обратите внимание, что этот код, по-видимому, постепенно завершается с ошибкой StackOverflow, но на самом деле это не так. Если вы повредите стек, удалив большие строки и рекурсивно вызвав StackOverflow, OOM не сработает, а SO-исключение не будет перехвачено. Это ограничениеPrepareConstrainedRegions (насколько мне известно). Смотрите также книгу Рихтера:books.google.nl/…
19

SQL Server для интеграции CLR в SQL Server 2005. Вероятно, чтобы другие могли использовать и, вероятно, по юридическим причинам, эта глубокая интеграция была опубликована как API хостинга, но техническими требованиями были SQL Server. Помните, что в SQL Server значение MTBF измеряется месяцами, а не часами, и перезапуск процесса из-за возникновения необработанного исключения совершенно неприемлем.

этоMSDN Magazine статья вероятно, это лучшее, что я видел, описывая технические требования, для которых была создана ограниченная среда исполнения.

ReliabilityContract используется для украшения ваших методов, чтобы указать, как они работают в условиях потенциально асинхронных исключений (ThreadAbortException, OutOfMemoryException, StackOverflowException). Ограниченная область выполнения определяется как секция catch или finally (или error) блока 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, с ним происходят две вещи. Способ будет предварительно подготовлен JIT, так что он не будет вызывать JIT-компилятор при первом его запуске, который может попытаться использовать саму память и вызвать собственные исключения. Кроме того, в то время как внутри CER среда выполнения обещает не генерировать исключение ThreadAbort и будет ждать выброса исключения до завершения CER.

Итак, вернемся к вашему вопросу; Я все еще пытаюсь найти простой пример кода, который прямо ответит на ваш вопрос. Как вы, возможно, уже догадались, самый простой пример потребует довольно много кода, учитывая асинхронный характер проблемы, и, вероятно, будет кодом SQLCLR, потому что это среда, которая будет использовать CER для большей выгоды.

Это не совсем правильно. CER также используется дляSafeHandles чтобы они были закрыты. Это включает в себя любой P / Invoke, приводящий к SafeHandle ОС (GDI +, файлы и т. Д.). Если вы начнете пропускать дескрипторы в Windows, вы скоро столкнетесь с проблемами.
-5

ияют на то, как CLR будет выполнять код в некоторых ситуациях, но я верю, что они (или их отсутствие) никогда не приведут к ошибке в текущих версиях .NET.

Они в основном «зарезервированы для будущего использования».

Несмотря на отрицательные голоса, отсутствие примеров по этому вопросу подтверждает мою точку зрения. CER не влияют на поток кода, включая блок finally. Они документируют код, поэтому фреймворк может относиться к нему по-другому По сути, это означает «я не буду поднимать асинхронные исключения, вы не прерываете меня асинхронными исключениями». Удаление CER никогда не нарушит код, хотя это может сделать статистически менее надежным. Также довольно очевидно, что CER могут использоваться гораздо больше, чем то, что в настоящее время реализуется во время выполнения.
Они являются документацией. Как я уже сказал, CLR читает и использует эту документацию - здесь нет никаких противоречий. Дело в том, что «короткая выборка ломается, если только [] не применяется». невозможно, ничто не сломается без атрибутов CER. Становится менее надежным - да, но ничего, что можно охарактеризовать как «взлом кода».
Атрибуты CER не только для документации; при использовании из ограниченной области выполнения метод, отмеченный с помощью ReliabilityContract, будет подготовлен перед выполнением JIT для предварительной компиляции, а память для метода будет предварительно выделена при входе в PrepareConstrainedRegions.
не невозможно, см. топ проголосовавших ответ Sam Saffron

Похожие вопросы