Форум: "Основная";
Текущий архив: 2009.10.04;
Скачать: [xml.tar.bz2];
ВнизAccess Violation в потоке Найти похожие ветки
← →
RAndrey (2008-08-07 17:52) [0]Добрый день!
Возникла такая неожиданная проблема.
В отдельном потоке создается объект 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;
← →
Medbe}I{onok XML © (2008-08-07 19:12) [1]И зачем ему в поток если
bt.Conn:=DM.Conn;
И где инициализация ole в потоке?
← →
RAndey (2008-08-07 20:03) [2]
> И зачем ему в поток если
>
> bt.Conn:=DM.Conn;
>
> И где инициализация ole в потоке?
Ну это можно поправить. Но неясно, при чем тут Access Violation?
← →
Palladin © (2008-08-07 20:39) [3]кто тебе разрешал Application пользоваться в потоке?
← →
Loginov Dmitry © (2008-08-07 20:56) [4]> В чем может быть дело? У меня идей уже не осталось...
1. Зачем мучаешь Application из доп. потока? Вместо этого указывай nil.
2. Код q.Connection:=Conn из доп. потока не безопасен! Создавай коннект в доп. потоке динамически, затем его и указывай.
← →
RAndey (2008-08-07 21:21) [5]1. Ну обычно так и делаю.
2. Переделал, но Access Violation по-прежнему периодически вылазит.
Спасибо за советы, я им обязательно последую, но вот простую вещь - не могу понять: почему первая строчка отрабатывает, а на второй - Access Violation?
SQL.Add("select max(ddatedoc) from bank..restanl");
Open;
← →
RAndey (2008-08-07 21:26) [6]
> кто тебе разрешал Application пользоваться в потоке?
А в чем разница? Мне с потоками работать приходится нечасто, да и программирую в последнее время редко, ьак что извиняюсь за явно дурацкий для Вас вопрос.
Если напишу nil, придется "убивать" потом (что делать лень :-) ), а с Application - убъется само.
← →
Loginov Dmitry © (2008-08-07 21:45) [7]> Если напишу nil, придется "убивать" потом (что делать лень
> :-) ), а с Application - убъется само.
С Application убъется при выходе из программы. Т.е. всю дорогу будут загружены в память ненужные объекты. А оно нужно?
← →
Loginov Dmitry © (2008-08-07 21:47) [8]Более того, метод procedure TComponent.InsertComponent(AComponent: TComponent); не является безопасным для обращений из доп. потоков.
← →
RAndey (2008-08-08 08:27) [9]
> Более того, метод procedure TComponent.InsertComponent(AComponent:
> TComponent); не является безопасным для обращений из доп.
> потоков.
А что делать, если надо создать объект? Можно, конечно, сделать поле класса TThread типа TADOQuery, и создавать его перед стартом потока... но как-то кривовато выглядит, по-моему.
← →
Сергей М. © (2008-08-08 08:38) [10]
> что делать, если надо создать объект?
Ну и создавай, кто ж мешает ?
Только не указывай владельцем потоконебезопасный объект, "живущий" совсем в другом потоке (в дан.случае TApplication) - указывай либо nil либо любой компонент, "живущий" в этом же потоке.
> Если напишу nil, придется "убивать" потом (что делать лень
А кому сейчас легко ?)
> создавать его перед стартом потока... но как-то кривовато
> выглядит
Нормально выглядит.
А кривизна в другом - активация объекта доступа к БД в одном потоке, а последующая работа с этим объектом в другом потоке.
В т.ч. и в 1-ю очередь это касается ADO-компонентов.
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2009.10.04;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.006 c