Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2003.03.24;
Скачать: CL | DM;

Вниз

Запутался с 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;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.014 c
1-76372
Zheka
2003-03-11 11:55
2003.03.24
Сортировка файлов в объекте - FileListBox


14-76603
DeMoN-777
2003-03-04 08:57
2003.03.24
Регистрация в поисковых системах


8-76536
zig
2002-12-10 13:02
2003.03.24
Label in TChart - формат вывода чисел


3-76286
Erden
2003-03-04 15:09
2003.03.24
Пароль на DB ...


3-76345
Mic_2000
2003-03-05 16:12
2003.03.24
Как сделать чтобы IBDatabase не конектился сам при запуске?