Код, демонстрирующий важность ограниченной области выполнения

StackOverflow https://stackoverflow.com/questions/1101147

  •  12-09-2019
  •  | 
  •  

Вопрос

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

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

Это было полезно?

Решение

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

Когда myFn активирован, он пытается создать ConstrainedRegion из блока finally.

  • В случае без ReliabilityContract надлежащий ConstrainedRegion не может быть сформирован, поэтому генерируется обычный код.Исключение переполнения стека генерируется при вызове Stackoverflow (после выполнения блока try).

  • В случае с ReliabilityContract может быть сформирован ограниченный регион, и требования к стеку методов в блоке finally могут быть перенесены в myFn.Исключение переполнения стека теперь генерируется при вызове myFn (до того, как блок try будет когда-либо выполнен).

Другие советы

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

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

ReliabilityContract используется для оформления ваших методов, чтобы указать, как они работают с точки зрения потенциально асинхронных исключений (ThreadAbortException, OutOfMemoryException, StackOverflowException).Область ограниченного выполнения определяется как раздел catch или finally (или fault) блока try, которому непосредственно предшествует вызов System.Runtime.Службы компилятора.Службы времени выполнения.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, потому что это среда, которая будет использовать CERS с наибольшей выгодой.

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

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

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

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

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

В основном они "зарезервированы для использования в будущем".

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top