Модераторы: Snowy, MetalFan, bems, Poseidon
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Что значит try и finally, Объясните новичку:) 
:(
    Опции темы
Andreyzpr
Дата 30.9.2007, 11:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 190
Регистрация: 4.2.2007
Где: Украина

Репутация: 1
Всего: 1



Не могу понять, что делает try и finally
Кто нибудь может рассказать для чего эти команды служат и что делают?
PM MAIL WWW ICQ   Вверх
MetalFan
Дата 30.9.2007, 11:35 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



обеспечивает выполнение кода finally-end даже если произошла ошибка между try-finally
используется например для 99,9% освобождения захваченных ресурсов.
Код


...
  lFileStream := TFileStream.Create(...)
  try
    lFileStream.xxxx
....
  finally
    lFileStream.Free;
  end;

в данном случае при возникновении ошибки между try-finally файл будет закрыт и память под объект будет освобождена


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
EvilsInterrupt
Дата 30.9.2007, 12:23 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Назначение, небольшие нюансы по исключениям.

Речь пойдет о конструкциях вида: try-finally-end; , try-except-end
1. Синтаксис.
Код

try
// попытка выполнить
finally
// завершающие действия
end;


Код

try
// Попытка выполнить
except
// Выполнить обработку ошибки или попытаться исправить ситуацию
end;


2. Работа конструкций.
Что происходит в случае применения конструкций?

Для того чтобы понять, что же происходит создадим прогу, добавим форму и кнопку, потом добавим ее обработчик с таким кодом:
Код

  procedure TfrmMain.Button1Click(Sender: TObject);
  var
    tmp,tmp2 : TCriticalSection;
  begin
    tmp := Nil;
    tmp2 := Nil;    
    try
      try
//        tmp := TCriticalSection.Create;
        tmp.Acquire;
        Memo1.Lines.Add('tmp');
        tmp.Release;
      finally
        Memo1.Lines.Add('finally1');
      end;
      try
        tmp2 := TCriticalSection.Create;
        tmp2.Acquire;
        Memo1.Lines.Add('tmp2');
        tmp2.Release;
      finally
        Memo1.Lines.Add('finally2');
      end;
    except
      on E : Exception do
         Memo1.Lines.Add('Except');
    end;
    tmp.Free;
    tmp2.Free;
  end;

Мы намерено не создали объект tmp !!! Чтобы посмотреть,  что же будет?

Код выполнится так:
1. Возникнет бага, мы же не создали объект критической секции и не присвоили ее tmp !
2. Попадаем в конструкцию между ключевыми словами  finally и end, там где вывод "Finally1"
3. После этого попадаем в конструкцию между ключевыми словами  except и end, там где вывод "except".

Возникает вопрос, а почему так? А почему не выполнился код, который между ключевыми словами finally и end, там где используется вывод "finally2" ?

А дело вот втом что когда мы используем try-конструкции Delphi инкапсулирует следующую работу:
1) Регистрация обработчика исключительной ситуации, а это часть кода между finally-end и except-end !!!
2) В обработчик передается объект исключения
3) В ситуации применения try-finally-end объект исключения созданный между try и finally не уничтожается, объект исключения передается следующему обработчику. В ситуации же примениния try-except-end объект искючения созданный между try и exсept, гарантированно уничтожается между словами except и end!!!

Из п.3 мы можем заключить, что в try-finally-end мы объект не убивается, потому управление получит код между except и end. Как только раскоментируем строку с созданием объекта tmp, то все будет ок!!!

3. Применение
Раз между finally-end не уничтожается объект исключения, то зачем тогда он нужен ? Хороший вопрос ;)

Дело в том что, код между код finally и end выполнится в любом случае, а код между except и end только когда будет исключение!!!
И в итоге try и finally нужен он для того чтобы , корректно завершить все действия связанные по уничтожению объекта!

Пример:
1. Попытка открыть файл позаписи
2. Попытка записать событие в лог-файл
3. Уничтожить объект

В случае если мы пункты разместим так:
Код

try
// 1.
// 2.
finally
// 3.
end;


то у нас будет корректно закрыт файл! Даже если произошла исключительная ситуация.

Нюанс!!!

А вдруг она произошла в п.1, то выполнится п3, но ведь объект исключения не уничтожается !!! Что будет дальше? А дальше все это дело можно обернуть в конструкцию try-except-end, где между try и except поместить наш код, а в except и end обработать наши ошибки. вот теперь все!

4. Запись от SAP (Петрович)`a:
Код

try try
// пытаемся выполнить
finally end
// уничтожаем объекты
except
// обрабатываем ошибки
end;


Нюанс от SAP (Петрович)`a
Код между finally-end выполнится в любом случае, даже если вызвали Exit! Вот доказательство его слов:
Код

  procedure TfrmMain.Button2Click(Sender: TObject);
  var
    tmp3 : TCriticalSection;
  begin
    tmp3 := Nil;
    try
      try
        tmp3.Acquire;
        Memo1.Lines.Add('First bug');
        tmp3.Release;
      except
        on E: Exception do
        begin
          Memo1.Lines.Add(E.Message);
          Exit;
        end;
      end;
    finally
      Memo1.Lines.Add('Finally-end');
    end;
  end;

Это означает что этот факт можно использовать для завершающих действий.

Это сообщение отредактировал(а) EvilsInterrupt - 1.10.2007, 12:58
PM MAIL WWW ICQ Jabber   Вверх
MetalFan
Дата 30.9.2007, 17:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



Цитата(EvilsInterrupt @  30.9.2007,  12:23 Найти цитируемый пост)
MetalFan, не совсем так, как описал ;)

я описал общий смысл без углубления в дебри обработки исключений в системе... зачем объяснять про то, как устроено SEH? был вопрос что такое try..finally, я на него ответил


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
EvilsInterrupt
Дата 30.9.2007, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Код

ро то, как устроено SEH?

Затем, что вопрошающий - это возможный будущий серьезный программер. И он обязан понимать, что во время возникновения баги, создается объект исключения! Это дает четкое понимание, что в последствии объект обязан быть уничтожен! Я этого поначалу непонимал, потому что это не сразу бросается в глаза.
PM MAIL WWW ICQ Jabber   Вверх
MetalFan
Дата 30.9.2007, 20:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Аццкий Сотона
****


Профиль
Группа: Комодератор
Сообщений: 3815
Регистрация: 2.10.2006
Где: Moscow

Репутация: 22
Всего: 128



Цитата(EvilsInterrupt @  30.9.2007,  18:54 Найти цитируемый пост)
это возможный будущий серьезный программер.

прально, надо запудрить ему мозг, чтоб он вообще ничего не понял... имхо надо объяснить сначало основы, а уж потом, если возникнут вопросы, 
углубляться в дебри.

Цитата(EvilsInterrupt @  30.9.2007,  18:54 Найти цитируемый пост)
И он обязан понимать, что во время возникновения баги, создается объект исключения! 

для программиста на делфи это совершенно прозрачно... тем более, что никакой прямой работы с SEH в делфи не требуется

Это сообщение отредактировал(а) MetalFan - 30.9.2007, 20:23


--------------------
There are always someone smarter than you...
PM MAIL   Вверх
Петрович
Дата 1.10.2007, 12:38 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1000
Регистрация: 2.12.2003
Где: Москва

Репутация: нет
Всего: 55



Согласен с MetalFan.

Цитата(EvilsInterrupt @  30.9.2007,  19:54 Найти цитируемый пост)
И он обязан понимать, что во время возникновения баги, создается объект исключения! Это дает четкое понимание, что в последствии объект обязан быть уничтожен!

Ну тогда попробуй объяснить в терминах языка Delphi где тут уничтожается объект исключения:
Код

try
// Попытка выполнить
except
// Выполнить обработку ошибки или попытаться исправить ситуацию
end;

smile
И вообще, где тут объект исключения?  Я лично не вижу! Хотя, коечно, как "опытный" программер понимаю что он там неявно существует.
Короче, действительно, не обязательно знать дельфисту что такое объект исключения. А вот как пользоваться try finally/except блоками действительно знать необходимо. Соответственно, если уж объяснять, то объяснять надо именно в терминологии Delphi а не WinAPI.

Это сообщение отредактировал(а) Петрович - 1.10.2007, 12:38


--------------------
Все знать невозможно, но хочется
PM ICQ   Вверх
bems
Дата 1.10.2007, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Объект исключения не обязательно уничтожается. Например для нехваток памяти используется созданый при старте программы объект, а потом он остается на случай если проблема снова возникнет (т.к. при нехватке памяти создать новый объект может и не получиться).
И вообще вести речь об уничтожении объекта исключения стоит только тогда, когда нарушен естественный ход процесса (например AcquireExceptionObject).
Цитата(Петрович @  1.10.2007,  12:38 Найти цитируемый пост)
Ну тогда попробуй объяснить в терминах языка Delphi где тут уничтожается объект исключения:
внутри пятой строки
Цитата(EvilsInterrupt @  30.9.2007,  12:23 Найти цитируемый пост)
Нюанс от SAP (Петрович)`a
Код между finally-end выполнится в любом случае, даже если вызвали Exit!
Ага. И goto и break и continue и halt. Вот то-то и оно, что конструкция
Код

try
finally
end;
вообще не имеет отношения к исключениям в смысле Дельфи, а предназначена для выполнения секции finally-end при любом выходе из секции try-finally

Добавлено через 3 минуты и 38 секунд
Цитата(EvilsInterrupt @  30.9.2007,  12:23 Найти цитируемый пост)
А вдруг она произошла в п.1, то выполнится п3, но ведь объект исключения не уничтожается !!! 
а вот там его вообще может не быть!!



--------------------
Обижено школьников: 8
PM MAIL   Вверх
EvilsInterrupt
Дата 1.10.2007, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: нет
Всего: 9



Цитата

Объект исключения не обязательно уничтожается.

Прошу привести код, который бы это демонстриовал или хотя бы по косвенным признакам могли бы судить о правильности ваших слов. Можно и цитату от мануала, но тогда указать мануал ;)

Цитата

вообще не имеет отношения к исключениям в смысле Дельфи

С каких это пор try-finally-end перстало являться исключением в смысле Delphi ?
Вот выдержка из справки к Delphi 2007 Update 1:
Цитата

Try...finally Statements
Sometimes you want to ensure that specific parts of an operation are completed, whether or not the operation is interrupted by an exception. For example, when a routine acquires control of a resource, it is often important that the resource be released, regardless of whether the routine terminates normally. In these situations, you can use a try...finally statement. 

The following example shows how code that opens and processes a file can ensure that the file is ultimately closed, even if an error occurs during execution. 
Код

Reset(F); 
try 
   ... // process file F 
finally 
   CloseFile(F); 
end;


PM MAIL WWW ICQ Jabber   Вверх
bems
Дата 3.10.2007, 13:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



Цитата(EvilsInterrupt @  1.10.2007,  19:24 Найти цитируемый пост)
С каких это пор try-finally-end перстало являться исключением в смысле Delphi ?
ну некоторая связь есть, в том смысле что для внешних исключений ибъект исключения создается именно в этой конструкции. Но приведенная тобой цитата говорит только что это можно использовать если предполагаешь исключения. А можно и для других целей.
Цитата(bems @  1.10.2007,  14:05 Найти цитируемый пост)
Ага. И goto и break и continue и halt
тут я преувеличил. только break,  continue и exit. Но все-таки исключений здесь нет, а конструкция работает.

Цитата(EvilsInterrupt @  1.10.2007,  19:24 Найти цитируемый пост)
Прошу привести код, который бы это демонстриовал или хотя бы по косвенным признакам могли бы судить о правильности ваших слов
ну вот же
Цитата(bems @  1.10.2007,  14:05 Найти цитируемый пост)
Например для нехваток памяти используется созданый при старте программы объект, а потом он остается на случай если проблема снова возникнет (т.к. при нехватке памяти создать новый объект может и не получиться).

это в SysUtils
Код

procedure InitExceptions;
begin
  OutOfMemory := EOutOfMemory.CreateRes(@SOutOfMemory);
  InvalidPointer := EInvalidPointer.CreateRes(@SInvalidPointer);
  ErrorProc := ErrorHandler;
тут мы видим создание объектов при инициализации. Потом делается raise уже для существующего объекта. И он не уничтожается до завершения модуля SysUtils


--------------------
Обижено школьников: 8
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0628 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.