![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
try..finally
Scott Storch © (2010-12-08 16:35:00)еще один вопрос: нудно ли FindFirst FindClose брать в try..finally?
Leonid Troyanovsky (2010-12-09 16:47:00) [1]
> Игорь Шевченко © (09.12.10 15:13) [30]
> много ли пользователей раннят программы андер дебуггером
Думаю, что не очень много.
Но, раньше у MS были проблемы как с повторным закрытием хендла,
так и c закрытием 0-хендла, даже без отладчика, поэтому уже давно
привык <> 0, и обнулять закрытые для избежания повторного.
Возможно, что в ранних версиях msdn остались этого следы.
--
Regards, LVT.
Anatoly Podgoretsky (2010-12-09 15:18:00) [2]> Leonid Troyanovsky (09.12.2010 13:11:29) [29]
Вот именно в FindClose и исправили.
Anatoly Podgoretsky (2010-12-09 15:17:00) [3]> Юрий Зотов (09.12.2010 12:51:28) [28]
Я уже писал, что у Борланда были проблемы в реализации функций Find, именно
с хендлом. С его нулевым значением.
Игорь Шевченко (2010-12-09 15:13:00) [4]
> If the application is running under a debugger
много ли пользователей раннят программы андер дебуггером ?
Leonid Troyanovsky (2010-12-09 13:11:00) [5]
> RWolf © (09.12.10 09:23) [22]
> а смысл? CloseHandle(0) ничего не делает.
Привык хендлы инициализировать 0.
А во-ще
If the application is running under a debugger, the function will throw an exception if it receives either a handle value that is not valid or a pseudo-handle value. This can happen if you close a handle twice, or if you call CloseHandle on a handle returned by the FindFirstFile function instead of calling the FindClose function.
--
Regards, LVT.
Юрий Зотов (2010-12-09 12:51:00) [6]> soldier (08.12.10 20:58) [7]
> Да, но это не ответ на сабж.
Это пример безопасного кода. А ответ или нет - пусть каждый сам решает.
> Здесь try..finally защищает не FindFirst, FindNext,
FindFirst защищать не надо, достаточно if (потому что если FindFirst не сработала, то и FindClose не нужна). FindNext защищать надо, потому что в общем случае неизвестно как эта эта функция реализована (даже если по ее сырцам мы видим, что СЕЙЧАС она вызвать исключение не может, то не факт, что ее реализация не изменится в дальнейшем).
> а другой код между repeat..until
Как правило, именно этот код больше всего в защите и нуждается.
================
Короче говоря, это пример построения компактного и безопасного кода вне зависимости от любых реализаций, текущих и будущих. Соответственно, и без необходимости заморачиваться по поводу реализаций. Именно такой стиль я считаю правильным, удобым и надежным - но никому, конечно, его не навязываю.
:o)
Rouse_ (2010-12-09 12:32:00) [7]
> soldier (08.12.10 22:55) [10]
>
> У меня нет делфей, но судя по
>
> Return Value
> If the function succeeds, the return value is nonzero.
> If the function fails, the return value is zero. To get
> extended error information, call GetLastError.
>
> Исключений она не вызывает.
Садись два, за слабо знание базы.
Как будет дельфи под рукой проверь вот такой код:
program Tst;
{$APPTYPE CONSOLE}
uses
Windows, SysUtils;
var
I: Integer;
begin
try
for I := 0 to 1000 do
CloseHandle(I);
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Anatoly Podgoretsky (2010-12-09 11:36:00) [8]> Ega23 (09.12.2010 10:31:24) [24]
DisableControls нужно внутрь блока для надежности.
Anatoly Podgoretsky (2010-12-09 11:34:00) [9]> RWolf (09.12.2010 09:23:22) [22]
Вообще то нельзя удалять не созданый ресурс, такая проблема была в Д3,
Борланд просто стал внутри проверять и ничего не делать если ресурс не
создан, а до этого происходила рантайм ошибка.
Ega23 (2010-12-09 10:31:00) [10]
> часто так делаю, ставлю try finally ради того чтобы свободно
> пользоваться break-ами, exit-ами внутри блока, чтобы при
> этом гарантированно сработали завершающие операции (не только
> освобождение ресурсов).
+100500.
with DataSet do
begin
DisableControls;
try
bm := GetBookmark;
try
First;
while not Eof do
begin
try
if FieldByName(...).... ..... then Continue
else
.....
finally
Next;
end;
finally
GotoBookmark(bm);
end;
finally
EnableControls;
end;
end;
sniknik (2010-12-09 10:00:00) [11]> Зачем ошибка, тривиальный EXIT и уже приплыли без finally
ага.
часто так делаю, ставлю try finally ради того чтобы свободно пользоваться break-ами, exit-ами внутри блока, чтобы при этом гарантированно сработали завершающие операции (не только освобождение ресурсов). код упрощается, не нужно диких нагромождений if-else, разделенный на логические блоки - инициализация, тело/обработчик, завершение.
RWolf (2010-12-09 09:23:00) [12]
> А если сама не вызывает, то вызвать, скажем, Win32Check.
> А перед CloseHandle проверить хендл на 0.
а смысл? CloseHandle(0) ничего не делает.
если, конечно, и её оборачивать в Win32Check, то да — но, опять же, незачем.
.
Anatoly Podgoretsky (2010-12-09 08:48:00) [13]
> А перед CloseHandle проверить хендл на 0.
А у ЮЗ не надо и там правильная конструкция, FindFirst выведен за пределы try finally
Anatoly Podgoretsky (2010-12-09 08:46:00) [14]
> а если внутри begin произойдет ошибка и до FindClose дело
> не дойдет, handle не освободится ведь, или я не прав.
Зачем ошибка, тривиальный EXIT и уже приплыли без finally
Anatoly Podgoretsky (2010-12-09 08:45:00) [15]
> soldier (08.12.10 20:58) [7]
> > Юрий Зотов © (08.12.10 18:27) [5]
>
> Да, но это не ответ на сабж. Здесь try..finally защищает
> не FindFirst, FindNext, а другой код между repeat..until,
> а сами функции не вызывают исключений (правда проверить
> не могу, дельфей нет, но ни одна функция апи их не вызывает).
>
А какое отношения к этому имеют исключения, finally это защита ресурсов, а не исключений, для этого другая конструкция except.
Anatoly Podgoretsky (2010-12-09 08:43:00) [16]
> soldier (08.12.10 22:55) [10]
A a/b вызывает?, а в трех точках может быть что угодно.
Германн (2010-12-09 02:38:00) [17]
> Игорь Шевченко © (09.12.10 00:27) [15]
> Leonid Troyanovsky © (09.12.10 00:34) [16]
>
>
Во накинулись, волки.
От Вас убудет что-ли если новичек первым правилом будет считать что нужно всегда использовать блок try..finally там, где что-то создается, используется, а потом уничтожается?
Детали можете объяснить в конференции WinAPI. Если автор туда доберётся.
Leonid Troyanovsky (2010-12-09 00:34:00) [18]
> DVM © (08.12.10 23:02) [13]
> да неважно, вызывает или нет, что теперь над каждой функцией
> гадать? При желании исключение можно схлопотать на любом
> ровном месте, так не лучше ли сразу брать за правило - захватили
> ресурс или начали парную операцию, в finally освободили.
А если сама не вызывает, то вызвать, скажем, Win32Check.
А перед CloseHandle проверить хендл на 0.
--
Regards, LVT.
Игорь Шевченко (2010-12-09 00:27:00) [19]
> При желании исключение можно схлопотать на любом ровном
> месте, так не лучше ли сразу брать за правило - захватили
> ресурс или начали парную операцию, в finally освободили
Марксизм не догма, а руководство к действию
soldier (2010-12-08 23:11:00) [20]Да ладно, ладно...
Я же обратного не утверждал.
И полностью согласен с тезисом "захватили ресурс или начали парную операцию, в finally освободили."