Существует три вида так называемых "асинхронных исключений". Это - ThreadAbortException, OutOfMemoryException и упомянутый StackOverflowException. Тем excepions позволяют произойти в любой инструкции в Вашем коде.
И, существует также способ преодолеть их:
самым легким является ThreadAbortException. Когда текущий код выполняется в наконец-блоке. ThreadAbortExceptions отчасти "перемещены" до конца наконец-блока. Таким образом, все в наконец-блоке не может быть прервано ThreadAbortException.
Во избежание OutOfMemoryException у Вас есть только одна возможность: ничего не выделяйте на "куче". Это означает, что Нельзя создать новые ссылочные типы.
Для преодоления StackOverflowException Вы нуждаетесь в некоторой помощи от Платформы. Эта справка проявляет в Принужденных регионах Выполнения. Необходимый стек выделяется прежде , фактический код выполнен и дополнительно также гарантирует, что код уже Скомпилирован в JIT и для этого доступен для выполнения.
существует три формы для выполнения кода в Принужденных регионах Выполнения (скопированный с Блог Команды BCL):
можно найти больше в этих сообщениях в блоге:
Принужденные регионы Выполнения и другие опечатки [Brian Grunkemeyer] в Блоге Команды BCL.
Блог Joe Duffy [приблизительно 112] Атомарность и асинхронные отказы исключения , где он дает очень хороший обзор по асинхронным исключениям и устойчивости в .net Платформе.
У меня есть ответ в MSDN Форум. Оказывается, я был почти у цели. По сути, статическая проверка работает лучше, если вы разделите контракты "и-ed". Итак, если мы изменим код на этот:
public static int RollDice(Random rng)
{
Contract.Ensures(Contract.Result<int>() >= 2);
Contract.Ensures(Contract.Result<int>() <= 12);
if (rng == null)
{
rng = new Random();
}
Contract.Assert(rng != null);
int firstRoll = rng.Next(1, 7);
Contract.Assume(firstRoll >= 1);
Contract.Assume(firstRoll <= 6);
int secondRoll = rng.Next(1, 7);
Contract.Assume(secondRoll >= 1);
Contract.Assume(secondRoll <= 6);
return firstRoll + secondRoll;
}
Это работает без проблем. Это также означает, что пример еще более полезен, поскольку он подчеркивает тот самый момент, что средство проверки действительно лучше работает с разделенными контрактами.
Я не знаю об инструменте MS Contracts Checker, но анализ диапазона - это стандартный метод статического анализа; он широко используется в коммерческих инструментах статического анализа для проверки законности подстрочных выражений.
MS Research имеет хорошую репутацию в этом виде статического анализа, и поэтому я ожидал, что проведение такого анализа диапазона будет целью Программа проверки контрактов, даже если в данный момент она не проверена.