Читаем Интернет-журнал "Домашняя лаборатория", 2007 №9 полностью

• В данном образце предполагается, что в теле охраняемого блока анализируется возможность возникновения исключительной ситуации и, в случае обнаружения опасности, выбрасывается собственное исключение, класс которого задан программно. В соответствии с этим тело 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 ());

     }

}

Перейти на страницу:

Похожие книги