Форум: "Основная";
Текущий архив: 2002.07.22;
Скачать: [xml.tar.bz2];
ВнизЧем вызвана ошибка Thread Creation error: No enought storage ... Найти похожие ветки
← →
Aleksandr (2002-07-09 12:58) [0]Я предполагаю, что ошибка связана с Coinitialize.
Суть такова:
Есть базовый поток, в котором вызывается Coinitialize(nil) при создании и Couninitialize в дестракторе. Вызываются эти функции, потому что в потомках этого потока (разных, иногда существующих в нескольких экземплярах каждый) используются TADOQuery (в базовом его нет). И по истечении какого-то периода работы программа начинает выдавать указанную ошибку. Может, причина в том, что Coinitialize следует вызывать только в самих потомках?
← →
Digitman (2002-07-09 13:05) [1]"при создании" - надо понимать "в теле конструктора" ?
Этио неверно. Конструктор вызвается другим потоком, а не тем, что собственно создается и в котором планируется обращение к OLE/COM
← →
Aleksandr (2002-07-09 13:14) [2]Так, не понял, что неверно. При создании - да, в теле констрактора. То есть у базового потока:
constructor TShowProgressThread.Create;
begin
Inherited Create(true);
Coinitialize(nil);
DoSomething
end;
destructor TShowProgressThread.Destroy;
begin
DoSomething;
Couninitialize;
Inherited
end;
у потомков:
constructor TQueryThread.Create;
begin
Inherited Create;
FQuery:=TblList.GetADOQuery;
DoSomething
end;
← →
Digitman (2002-07-09 13:21) [3]вот это
procedure TSomeThread.Execute;
begin
Coinitialize(nil);
try
finally
Couninitialize;
end;
end;
верно.
Все остальное (что ты привел) - нет.
← →
Aleksandr (2002-07-09 13:25) [4]Оппа... SomeThread, соответственно - потомок, коли Execute у всех перекрывается? А почему так? И еще вопрос, если можно - в программе есть список - потомок TList, потокам не принадлежащий, который создает эти самые TADOQuery для потоков по их вызовам. В нем Coinitialize не нужна?
← →
Aleksandr (2002-07-09 13:30) [5]Просто у меня глобальная проблема в организации программы предыдущим автором. Он в базовом потоке закрывал Execute, делая его выполнение следующим образом:
procedure TShowProgressThread.Execute;
begin
DoSomething;
DoExecute;
DoSomething
end;
и в потомках уже перекрывался DoExecute... Поэтому execute мне недоступен.
← →
Digitman (2002-07-09 13:56) [6]И правильно делал "предыдущий автор") ... Coinitialize/CoUninitialize() нужно вызывать ТОЛЬКО в переопределенном вирт.методе TThread.Execute
← →
Aleksandr (2002-07-09 14:29) [7]Ничего не понимаю... Так где мне вызывать Coinitialize - у базового потомка TShowProgressThread или полностью перекрывать его Execute в его потомках и вызывать в них? :(
← →
Aleksandr (2002-07-09 14:36) [8]Или вообще мона сделать так:
procedure TQueryThread.DoExecute;
begin
Coinitialize(nil);
try
DoSomething;
finally
Couninitialize
end
end;
Execute у него по-прежнему отсутствует, вместо него базовый:
procedure TShowProgressThread.Execute;
begin
DoSomething;
DoExecute;
DoSomething
end;
← →
Digitman (2002-07-09 14:42) [9]если
TShowProgressThread.DoExecute; virtual; abstract;
а
TQueryThread.DoExecute; override;
то
procedure TQueryThread.DoExecute;
begin
Coinitialize(nil);
try
DoSomething;
finally
Couninitialize
end
end;
← →
Aleksandr (2002-07-09 15:32) [10]Большое спасибо! Только базовый DoExecute не abstract, а просто virtual - когда она писалась, такого еще не было. А потомок - override. Надеюсь, это не повлияет?
← →
Digitman (2002-07-09 15:59) [11]Нет, не повлияет
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2002.07.22;
Скачать: [xml.tar.bz2];
Память: 0.46 MB
Время: 0.008 c