Партнерка на США и Канаду по недвижимости, выплаты в крипто
- 30% recurring commission
- Выплаты в USDT
- Вывод каждую неделю
- Комиссия до 5 лет за каждого referral
Схема Бертрана является схемой с возобновлением, и она наиболее точно описывает разумную стратегию обработки исключительных ситуаций. Не следует думать, что эта схема не может быть реализована на C#, просто она требует понимания сути и определенной структурной организации модуля. Приведу возможную реализацию такой схемы на C#:
public void Pattern()
{
do
{
try
{
bool Danger = false;
Success = true;
MakeJob();
Danger = CheckDanger();
if (Danger)
throw (new MyException());
MakeLastJob();
}
catch (MyException me)
{
if(count > maxcount)
throw(new MyException("Три попытки были безуспешны"));
Success = false; count++;
//корректировка ситуации
Console. WriteLine("Попытка исправить ситуацию!");
level +=1;
}
}while (!Success);
}
Приведу краткие комментарии к этой процедуре, которую можно рассматривать как некоторый образец организации обработки исключительной ситуации:
· Конструкция try-catch блоков помещается в цикл do-while(!Success), завершаемый в случае успешной работы охраняемого блока, за чем следит булева переменная Success.
· В данном образце предполагается, что в теле охраняемого блока анализируется возможность возникновения исключительной ситуации и в случае обнаружения опасности выбрасывается собственное исключение, класс которого задан программно. В соответствии с этим тело try-блока содержит вызов метода MakeJob, выполняющего некоторую часть работы, после чего вызывается метод CheckDanger, выясняющий, не возникла ли опасность нарушения спецификации и может ли работа быть продолжена. Если все нормально, то выполняется метод MakeLastJob, выполняющий заключительную часть работы. Управление вычислением достигает конца try-блока, он успешно завершается и, поскольку остается истинной переменная Success, значение true которой установлено в начале try-блока, то цикл while, окаймляющий охраняемый блок и его обработчиков исключений, успешно завершается.
· Если в методе CheckDanger выясняется, что нормальное продолжение вычислений невозможно, то выбрасывается исключение класса MyException. Это исключение перехватывает обработчик исключения, стоящий за try-блоком, поскольку класс MyException указан, как класс формального аргумента.
· Для простоты приведен только один catch-блок. В общем случае их может быть несколько, но все они строятся по единому образцу. Предполагается, что обработчик исключения может сделать несколько попыток исправить ситуацию, после чего повторно выполняется охраняемый блок. Если же число попыток, за которым следит переменная count, превосходит максимально допустимое, то обработчик исключения выбрасывает новое исключение, задавая дополнительную информацию, передавая тем самым обработку ошибки на следующий уровень – вызываемой программе.
· Когда число попыток еще не исчерпано, то обработчик исключения переменной Success дает значение false, гарантирующее повтор выполнения try-блока, увеличивает счетчик числа попыток и пытается исправить ситуацию.
· Как видите, эта схема реализует два корректных исхода обработки исключительной ситуации – Retry и Rescue – повтору с надеждой выполнить обязательства, и передачи управления вызывающей программе, чтобы она предприняла попытки исправления ситуации, когда вызванная программа не могла с этим справиться.
Доведем этот образец до реально работающего кода, где угроза исключения зависит от значения генерируемого случайного числа, а обработчик исключения может изменять границы интервала, повышая вероятность успеха.
Определим первым делом собственный класс исключений:
public class MyException :Exception
{
public MyException()
{}
public MyException (string message) : base(message)
{}
public MyException (string message, Exception e) : base(message, e)
{}
}
Минимально, что нужно сделать, определяя свои исключения, – это задать три конструктора класса, вызывающие соответствующие конструкторы базового класса Exception.
В классе Excepts, методом которого является наш образец Pattern, определим следующие поля класса:
Random rnd = new Random();
int level = -10;
bool Success; //true - нормальное завершение
int count =1; // число попыток выполнения
const int maxcount =3;
Определим теперь методы, вызываемые в теле охраняемого блока:
void MakeJob()
{
Console. WriteLine("Подготовительные работы завершены");
}
bool CheckDanger()
{
//проверка качества и возможности продолжения работ
int low = rnd. Next(level,10);
if ( low > 6) return(false);
return(true);
}
void MakeLastJob()
{
Console. WriteLine("Все работы завершены успешно");
}
В классе Testing зададим метод, вызывающий метод Pattern:
public void TestPattern()
{
Excepts ex1 = new Excepts();
try
{
ex1.Pattern();
}
catch (Exception e)
{
Console. WriteLine("исключительная ситуация при вызове Pattern");
Console. WriteLine(e. ToString());
}
}
Обратите внимание, вызов метода Pattern находится внутри охраняемого блока. Поэтому, когда Pattern не справится с обработкой исключительной ситуации, ее обработку возьмет на себя универсальный обработчик, стоящий за try-блоком.
На рис. 23.6 показаны три варианта запуска метода TestPattern. В одном из них исключительной ситуации при вызове метода Pattern вообще не возникало, в другом – ситуация возникала, но коррекция обработчика исключения помогла и при повторе выполнения охраняемого блока в Pattern все прошло нормально. В третьем варианте метод Pattern не смог справиться с исключительной ситуацией, и она обрабатывалась в catch-блоке метода TestPattern.
Класс Exception
Рассмотрим устройство базового класса Exception, что поможет понять, какую информацию может получить обработчик исключения, когда ему передается объект, задающий текущее исключение.
Основными свойствами класса являются:
· Message – строка, задающая причину возникновения исключения. Значение этого свойства устанавливается при вызове конструктора класса, когда создается объект, задающий исключение.
· HelpLink – ссылка (URL) на файл, содержащий подробную справку о возможной причине возникновения исключительной ситуации и способах ее устранения.
· InnerException – ссылка на внутреннее исключение. Когда обработчик исключение выбрасывает новое исключение для передачи обработки на следующий уровень, то текущее исключение становится внутренним для вновь создаваемого исключения.
· Source – имя приложения, ставшего причиной исключения.
· StackTrace – цепочка вызовов – методы, хранящиеся в стеке вызовов в момент возникновения исключения.
· TargetSite – метод, выбросивший исключение.
Из методов класса отметим метод GetBaseException, – при подъеме по цепочке вызовов позволяет получить исходное исключение – первопричину возникновения последовательности выбрасываемых исключений.
Класс имеет четыре конструктора, из которых три уже упоминалось. Один из них – конструктор без аргументов, второй – принимает строку, становящуюся свойством Message, третий – имеет еще один аргумент – исключение, передаваемое свойству InnerException.
В предыдущий пример я внес некоторые изменения. В частности, добавил еще один аргумент при вызове конструктора исключения в catch-блоке метода Pattern:
throw(new MyException("Все попытки Pattern безуспешны", me));
В этом случае у создаваемого исключения заполняется свойство InnerExceptions. Для слежения за свойствами исключений добавил метод печати всех свойств, вызываемый во всех обработчиках исключений:
static public void PrintProperties(Exception e)
{
Console. WriteLine("Свойства исключения:");
Console. WriteLine("TargetSite = {0}", e. TargetSite);
Console. WriteLine("Source = {0}", e. Source);
Console. WriteLine("Message = {0}",e. Message);
if (e. InnerException == null)
Console. WriteLine("InnerException = null");
else Console. WriteLine("InnerException = {0}", e. InnerException. Message);
Console. WriteLine("StackTrace = {0}", e. StackTrace);
Console. WriteLine("GetBaseException = {0}", e. GetBaseException());
}
Из-за громоздкости не привожу результаты, но отмечу, что они соответствуют описанию, приведенному в тексте лекции.
В заключение темы исключений хочу еще раз подчеркнуть, что корректное применение механизма исключений должно поддерживаться целенаправленными усилиями программиста. Следует помнить о двух важных правилах:
· обработка исключений должна быть направлена не столько на уведомление о возникновении ошибки, сколько на корректировку возникшей ситуации;
· если исправить ситуацию не удается, то программа должна быть прервана, не приводя к получению некорректных результатов, не удовлетворяющих спецификациям программы.
Вариант 1
1. Классы Debug и Trace:
q имеют разный набор свойств и методов, используемых для класса Debug в интересах отладки, для класса Trace – в интересах трассировки;
q если в конфигурации проекта вызываются методы и свойства класса Debug, то в этой конфигурации не вызываются методы класса Trace и наоборот;
q если в конфигурации вызываются методы и свойства класса Debug, то в этой конфигурации вызываются методы и свойства класса Trace;
q если в конфигурации вызываются методы и свойства класса Trace, то в этой конфигурации вызываются методы и свойства класса Debug;
q классы Trace и Debug имеют одинаковый набор свойств и методов.
2. Отметьте истинные утверждения:
q в тексте охраняемого блока всегда должен присутствовать оператор throw, выбрасывающий исключение;
q никакая программа не может быть корректной по отношению к произвольным спецификациям;
q вывод, поступающий от методов класса Debug, может быть направлен только одному, заранее выбранному слушателю;
q если блок finally сопровождает охраняемый блок, то он всегда будет выполняться;
q правильно организованная отладка позволяет доказать корректность программы.
3. Оператор throw:
q передает управление catch-блоку, следующему за try-блоком;
q может вызываться без аргументов;
q имеет два аргумента;
q вызывает прерывание процесса вычислений охраняемого блока;
q создает исключение – объект класса, производного от Exception.
Вариант 2
1. Блоки catch:
q всегда должны следовать за охраняемым блоком;
q получают управление при возникновении исключительной ситуации и выполняются в порядке их следования;
q только один из блоков, следующих за try-блоков, захватывает управление вычислением;
q выбрасывают исключение для передачи управления вызывающему методу;
q после корректировки причины, вызвавшей исключение, при достижении конца блока возвращают управление в точку возникновения исключения.
2. Отметьте истинные утверждения:
q устойчивость программной системы означает, что малым изменениям спецификации соответствуют малые изменения программного текста;
q невыполнение утверждения Assert приводит к выбрасыванию исключения;
q схема обработки исключений в C# – это схема с возобновлением;
q для каждого проекта по умолчанию создаются две конфигурации;
q блок finally выполняется только, если в охраняемом блоке выброшено исключение.
3. Атрибут условной компиляции Conditional:
q может задаваться для метода и класса;
q может задаваться только для метода;
q может задаваться для метода и отдельного оператора;
q в качестве аргумента принимает только константу условной компиляции;
q в качестве аргумента принимает выражение над константами условной компиляции.
Вариант 3
1. Класс Exception:
q является родительским классом для всех классов, задающих исключение;
q является родительским классом для всех классов библиотеки FCL, задающих исключение, но не классов, определенных пользователем;
q является абстрактным классом;
q имеет метод throw для выбрасывания исключений;
q позволяет задать файл, содержащий подробную справку о причине исключения и способах его устранения.
2. Отметьте истинные высказывания:
q к исключительным относятся только такие ситуации, которые обнаруживаются операционной системой, когда она не может выполнить предписанные программой действия;
q если метод имеет атрибут условной компиляции, то вызов метода может игнорироваться при компиляции программы;
q метод с предусловием False всегда корректен;
q классы Debug и Trace разделяют единую коллекцию слушателей;
q catch-блок не возвращает управление в охраняемый блок.
3. Метод Assert:
q позволяет контролировать корректность выполнения вычислений;
q останавливает вычисления, когда утверждение Assert нарушается;
q является средством периода отладки;
q заменяет механизм исключений;
q при нарушении утверждения открывает специальное диалоговое окно.
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 |


