![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как "убить" созданный THREAD [D5, Win95/98, Win2k, WinXP]
AlexG © (2004-10-13 15:57:00)Не хочу я, чтобы продолжал работу мой поток. И мне нужно его остановить, но сразу, чтобы он не доделывал работу, которую он будет доделывать, если ему сказать Terminate. Например он пытается соединиться с БД и процесс затянулся. Если ему просто сказать, чтобы он остановился (Terminate)? то он дождется завершения работы соединения, и только потом закроется. А мне все равно в каком он состоянии, хочу чтобы он был закрыт. Как мне это сделать?
AlexG (2004-10-21 10:59:00) [1]http://delphimaster.ru/cgi-bin/forum.pl?id=1097649858&n=1
http://delphimaster.ru/cgi-bin/forum.pl?id=1097655754&n=1
Если так интересно, то советую еще эти ветки посмотреть. Там обсуждается одно и то же...
VMcL (2004-10-21 07:40:00) [2]>> AlexG © (19.10.04 11:59) [18]
> Код пока не дам, т.к. не вижу смысла в этом.
Тогда жди телепатов...
AlexG (2004-10-19 11:59:00) [3]//Erik1 © (19.10.04 11:42) [17]
Ты не знаешь, а говоришь... :) Спокойнее, про гонишь - это вообще никуда не годится. Код пока не дам, т.к. не вижу смысла в этом. Там все обычное. Я объясню ситуацию.
Я создал поток, в котором есть внутренний член TADOConnection. В Excecute происходит попытка соединения с БД. ADOConnection настраивается так, чтобы был асинхронный доступ, т.к. иначе основной поток все равно забивается. Так вот, событие OnClose не наступает до тех пор, пока не пройдет соединение или не отвалится по таймауту. Да, это странно, но оно так. Проверено. И поток не удается убить даже этим TerminateThread: процесс идет дальше,т.е. все ждет таймаута и только потом закрывается диалоговое окно.
Я выход нашел, но мне это все кажется немного странным, т.к. не знаю как эта адоха работает. Я понял, что она работает посредством COM, но почему она не дает себя "убить", и почемц нужно задавать модель многопоточности именно MTA, а не STA. Хотя понятно почему... :) Теперь понятно ;)
Erik1 (2004-10-19 11:42:00) [4]Программа небудет ждать даже если ты просто запустиш соеденение с базой из треда! Так, что ты гониш, давай код.
AlexG (2004-10-19 09:35:00) [5]>Дмитрий Ботвин (14.10.04 10:48) [3]
>Как это не получается? TerminateThread-у похрену какой поток
>рубить. Какая ошибка выходит???
Ошибка не выходит. Просто программа так же ждет окончания работы подсоединения к БД.
VMcL (2004-10-15 23:42:00) [6]> А поскольку мы нить уже терминировали, но данный хендл теоретически может быть использован для другого ядрённого объекта
Эт я прогнал. Sorry.
VMcL (2004-10-15 23:38:00) [7]>> VMcL © (15.10.04 15:50) [13]
> Сейчас под рукой Delphi нет, чтобы проверить, но AFAIR, при вызове деструктора MyThread срейзится Exception, поскольку MyThread.Handle уже недействителен.
Пришел домой. Посмотрел (D6). Exception не рейзится. Так что с этим всё в порядке. Но в деструкторе класса TThread есть такой код:
if FHandle <> 0 then CloseHandle(FHandle);
А поскольку мы нить уже терминировали, но данный хендл теоретически может быть использован для другого ядрённого объекта, чей хендл мы в таком случае закроем. Это есть нехорошо.
VMcL (2004-10-15 15:50:00) [8]>> Дмитрий Ботвин (14.10.04 14:07) [10]
begin
TerminateThread(MyThread.Handle, 0);
MyThread.Free;
end;
Сейчас под рукой Delphi нет, чтобы проверить, но AFAIR, при вызове деструктора MyThread срейзится Exception, поскольку MyThread.Handle уже недействителен.
>> KSergey c (15.10.04 08:09) [11]
Тем не менее ресурсы все равно можно (а часто и нужно) освободить в деструкторе. Вот пример:
...
interface
type
TTest = class(TThread)
private
FSomeMem: Pointer;
protected
procedure Execute; override;
public
destructor Destroy; override;
end;
implementation
procedure TTest.Execute;
begin
// ...
FSomeMem := AllocMem(Random(50000));
// ...
if SomeCondition then
begin
FreeMem(FSomeMem);
FSomeMem := nil;
end;
// ...
end;
destructor TTest.Destroy;
begin
if FSomeMem <> nil then
FreeMem(FSomeMem);
inherited Destroy;
end;
end.
Rouse_ (2004-10-15 11:14:00) [9]Сори, тест...
KSergey (2004-10-15 08:09:00) [10]> [10] Дмитрий Ботвин (14.10.04 14:07)
Только при условии, что захвачены они были в конструкторе и высвобождаются в деструкторе. Что далеко не всегда так, а часто - по определению невозможно (динамическое выделение блоков памяти в процессе работы, например; считаем, что в конктрукторе выделить их нельзя, т.к. заранее неизвестен объем)
Дмитрий Ботвин (2004-10-14 14:07:00) [11]Вот это уничтожит поток и освободит ресурсы:
begin
TerminateThread(MyThread.Handle,0);
MyThread.Free;
end;
VMcL (2004-10-14 14:01:00) [12]>> Дмитрий Ботвин (14.10.04 13:46) [8]
После уничтожения функцией TerminateThread(), да ну? Или имеется в виду уничтожение объекта класса TThread?
Дмитрий Ботвин (2004-10-14 13:46:00) [13]Нет, если указать FreeOnTerminate:=true, то и ресурсы освободятся
после уничтожения потока....
KSergey (2004-10-14 13:41:00) [14]> [6] tesseract (14.10.04 13:06)
> Точно сказать нельзя, возможно Delphi автоматом
> выполнит Terminate после такой экзекуции, но скорей всего
> нет.
Нет. Ресурсы убьются только системой при завершении приложения.
tesseract (2004-10-14 13:06:00) [15]А той что после такого выхода из потока не освободяться ресурсы содержащиеся в потоке (не выполниться FonTerminate и Destroy). Точно сказать нельзя, возможно Delphi автоматом выполнит Terminate после такой экзекуции, но скорей всего нет.
Дмитрий Ботвин (2004-10-14 12:49:00) [16][4] TerminateThread = Утечка памяти и баги в программе.
Не понял о какой утечке и о каких багах идет речь?????
tesseract (2004-10-14 12:44:00) [17]TerminateThread = Утечка памяти и баги в программе. лучше доработай процесс соединения с базой - там что таймаута нет?
Дмитрий Ботвин (2004-10-14 10:48:00) [18]Как это не получается? TerminateThread-у похрену какой поток
рубить. Какая ошибка выходит???
AlexG (2004-10-14 10:18:00) [19]У меня не получается. Правда в этом потоке у меня происходит соединение с базой...
Дмитрий Ботвин (2004-10-13 16:01:00) [20]с помощью API-функции: TerminateThread(MyThread.Handle,0);
Срубит его мгновенно