Форум: "Основная";
Текущий архив: 2003.03.24;
Скачать: [xml.tar.bz2];
ВнизЗапутался с try ... finally ... end; Найти похожие ветки
← →
andrey_pst (2003-03-13 09:02) [0]Уважаемые, объясните, пожалуйста, вот такую ситуацию:
Есть код:
...
try
repeat
try
{ блок 1 }
finally
{ блок 2 }
end;
until ...;
finally
{ блок 3 }
end;
...
Вопрос:
Если исключение происходит в { блок 1 } выполняется { блок 2 }.
А { блок 3 } в "пролете", или тоже выполняться должен ?
← →
Polevi (2003-03-13 09:04) [1]должен
← →
Vlad V. Oshin (2003-03-13 09:05) [2]чай проверь, отладчиком
← →
Anatoly Podgoretsky (2003-03-13 09:06) [3]Ну почему в пролете, поставь в блоке 2 и 3 ShowMessage и все узнаешь
← →
pasha676 (2003-03-13 09:09) [4]Если я с утра еще соображаю, то выполняется блок1, если он не получился, то блок2, если не получилась вся конструкция между верхними try-finaly (весь цикл repeat-until) - то блок3.
Т.е. блоку3 собственно пофигу что там выполняется блок1 или блок2. Главное чтоб все посовокупности выполнилось.
← →
Vlad V. Oshin (2003-03-13 09:17) [5]
> блоку3 собственно пофигу
вообще все...
← →
stone (2003-03-13 09:38) [6]
> Если я с утра еще соображаю, то выполняется блок1, если
> он не получился, то блок2, если не получилась вся конструкция
> между верхними try-finaly (весь цикл repeat-until) - то
> блок3.
Поскольку в обоих случаях используется try-finaly то и блок2 и блок3 выполняются в любом случае, независимо были исключения или нет
← →
Юрий Зотов (2003-03-13 09:40) [7]А нужен ли воообще внутренний try-finally в ТАКОЙ конструкции?
← →
Roma (2003-03-13 09:47) [8]Наверно да, чтобы цикл продолжился...
> andrey_pst © (13.03.03 09:02)
То, что между finally и end, выполняется всегда...
← →
Dim!S (2003-03-13 09:49) [9]Насколько я знаю :) блок 2 и 3 будет выполньться ВСЕГДА, на то он и finally, вот если бы except стоял, ну тогда совсем другая схема...
← →
Anatoly Podgoretsky (2003-03-13 09:55) [10]Roma © (13.03.03 09:47)
Нет цикл продолжать не будет, поскольку будет выход из него до ближайшего обработчика ошибки.
← →
Юрий Зотов (2003-03-13 10:12) [11]> Roma © (13.03.03 09:47)
> И всем сомневающимся
Если в блоке 1 возникнет исключение, то будет выполнен сначала блок 2, затем прервется выполнение цикла и будет выполнен блок 3, а затем произойдет выход из процедуры. Это однозначно.
Поэтому и возникает вопрос - зачем нужен внутренний try-finally, если все необходимые действия можно выполнить во внешнем?
← →
andrey_pst (2003-03-13 10:41) [12]внутри цикла:
1) создается объект
2) выполняются действия с ним
3) уничтожается объект
...
try
repeat
try
att := TMyObj.Create(...);
...
finally
att.Free;
end;
until ...;
finally
{ блок 3 }
end;
...
попробовал в { блок 3 } написать
if Assigned(att) then
att.Free;
получил матюгальник: Acces Violation .......
потому, собственно и загрузился :)
← →
Roma (2003-03-13 11:16) [13]Мда... Извините, ошибся...
← →
Saint_Byte (2003-03-13 11:18) [14]Как все хитро -)
← →
vvolkov (2003-03-13 11:23) [15]Проблема в том, что исключение возникло в конструкторе объекта TMyObj. В строчке:
att := TMyObj.Create(...);
В этом случае неправомерным является вызов деструктора, а также само обращение к переменной att (поскольку присваивание еще не произошло). Правомерным в данном случае будет код:
att := TMyObj.Create(...);
try
...
finally
att.Free;
end;
При этом если в конструкторе возникнут исключения finally не будет исполняться.
← →
altarasjuk (2003-03-13 11:47) [16]Обработается {блок 2}, а затем, когда пройдёт Repeat...Until - выполниться {блок 3}
← →
raycdg (2003-03-13 12:03) [17]try..finally не обрабатывает исключения, а только выполняет действия, заключенные между finally..end в ЛЮБОМ случае. Для отлова исключения нужен try..except
Сделай, например, так:
...
repeat
att := TMyObj.Create(...);
try
...
except
end;
FreeAndNil(att);
until ...;
...
← →
Владислав (2003-03-13 12:53) [18]> raycdg (13.03.03 12:03)
В корне неверная конструкция. Ресурсы так не защищают.
← →
Юрий Зотов (2003-03-13 14:08) [19]> andrey_pst
1. НИКОГДА не включайте создание/захват защищаемого ресурса ВНУТРЬ защищенного блока. Если при его создании/захвате произойдет исключение, то освобождать ничего не надо, потому что освобождать просто нечего.
На что Вы и напоролись - при исключении в конструкторе объект уничтожается автоматически в том же конструкторе. В итоге ссылка Att оказывается неверной и в finally при попытке уничтожить несуществующий объект Вы получаете ВТОРОЕ исключение.
2. Зачем пересоздавать объект при каждом проходе цикла? Не лучше ли создать его ОДИН раз, а в цикле только выполнять необходимые перенастройки? И тогда вложенный защищенный блок становится уж точно ненужным.
В итоге получаем простую, понятную и более эффективную конструкцию:
Att := TMyObj.Create(...);
try
repeat
...
until ...
finally
Att.Free
end;
Или аналогичную ей, но без лишней переменной:
with TMyObj.Create(...) do
try
repeat
...
until ...
finally
Free
end;
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.03.24;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.008 c