![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Access Violation в потоке [D7, WinXP]
RAndrey © (2008-08-07 17:52:00)Добрый день!
Возникла такая неожиданная проблема.
В отдельном потоке создается объект TADOQuery:
q:=TADOQuery.Create(Application);
q.Connection:=Conn;
q.CommandTimeout:=0;
with q do begin
Close;
SQL.Clear;
SQL.Add('select max(ddatedoc) from bank..restanl');
Open;
datalast:=Fields[0].AsDateTime;
end;
И периодически (не при каждом запуске) и на разных строках возникает Access Violation. Например, SQL.Add проходит, а на Open - ошибка.
Объект создан и удаляется только после исполнения этого кода, поток запускается только один. В чем может быть дело? У меня идей уже не осталось...
Вот код, создающий поток:
bt:=BankThread.Create(True);
bt.Conn:=DM.Conn;
bt.FreeOnTerminate := True;
bt.Priority := tpNormal;
bt.Resume;
Сергей М. (2008-08-08 08:38:00) [1]
> что делать, если надо создать объект?
Ну и создавай, кто ж мешает ?
Только не указывай владельцем потоконебезопасный объект, "живущий" совсем в другом потоке (в дан.случае TApplication) - указывай либо nil либо любой компонент, "живущий" в этом же потоке.
> Если напишу nil, придется "убивать" потом (что делать лень
А кому сейчас легко ?)
> создавать его перед стартом потока... но как-то кривовато
> выглядит
Нормально выглядит.
А кривизна в другом - активация объекта доступа к БД в одном потоке, а последующая работа с этим объектом в другом потоке.
В т.ч. и в 1-ю очередь это касается ADO-компонентов.
RAndey (2008-08-08 08:27:00) [2]
> Более того, метод procedure TComponent.InsertComponent(AComponent:
> TComponent); не является безопасным для обращений из доп.
> потоков.
А что делать, если надо создать объект? Можно, конечно, сделать поле класса TThread типа TADOQuery, и создавать его перед стартом потока... но как-то кривовато выглядит, по-моему.
Loginov Dmitry (2008-08-07 21:47:00) [3]Более того, метод procedure TComponent.InsertComponent(AComponent: TComponent); не является безопасным для обращений из доп. потоков.
Loginov Dmitry (2008-08-07 21:45:00) [4]> Если напишу nil, придется "убивать" потом (что делать лень
> :-) ), а с Application - убъется само.
С Application убъется при выходе из программы. Т.е. всю дорогу будут загружены в память ненужные объекты. А оно нужно?
RAndey (2008-08-07 21:26:00) [5]
> кто тебе разрешал Application пользоваться в потоке?
А в чем разница? Мне с потоками работать приходится нечасто, да и программирую в последнее время редко, ьак что извиняюсь за явно дурацкий для Вас вопрос.
Если напишу nil, придется "убивать" потом (что делать лень :-) ), а с Application - убъется само.
RAndey (2008-08-07 21:21:00) [6]1. Ну обычно так и делаю.
2. Переделал, но Access Violation по-прежнему периодически вылазит.
Спасибо за советы, я им обязательно последую, но вот простую вещь - не могу понять: почему первая строчка отрабатывает, а на второй - Access Violation?
SQL.Add('select max(ddatedoc) from bank..restanl');
Open;
Loginov Dmitry (2008-08-07 20:56:00) [7]> В чем может быть дело? У меня идей уже не осталось...
1. Зачем мучаешь Application из доп. потока? Вместо этого указывай nil.
2. Код q.Connection:=Conn из доп. потока не безопасен! Создавай коннект в доп. потоке динамически, затем его и указывай.
Palladin (2008-08-07 20:39:00) [8]кто тебе разрешал Application пользоваться в потоке?
RAndey (2008-08-07 20:03:00) [9]
> И зачем ему в поток если
>
> bt.Conn:=DM.Conn;
>
> И где инициализация ole в потоке?
Ну это можно поправить. Но неясно, при чем тут Access Violation?
Medbe}I{onok XML (2008-08-07 19:12:00) [10]И зачем ему в поток если
bt.Conn:=DM.Conn;
И где инициализация ole в потоке?