![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Коннект к базе в дополнительном потоке
Piter © (2005-08-29 23:50:00)Вот думаю - как правильно реализовать соединение с базой в отдельном потоке.
Допустим, есть класс от TThread... Но как им управлять?
Хочется реализовать так, чтобы ему можно было дать любое SQL выражение, он его выполнит. Ну если с INSERT, UPDATE понятно... То что делать с SELECT? Как поток вернет набор данных?
Piter (2005-09-18 00:05:00) [1]А теперь такой вопрос - а если нужно передавать данные SELECT'а в стороннюю DLL (плагин) - то как поступать? То есть, движок базы реализован в самой программн, плагин в виде DLL делает запрос - ок... а как ему вернуть данные?
Надо учесть, что плагин и на C++ может быть написал, и на D, и на чем угодно...
Alexander Panov (2005-08-31 09:04:00) [2]А про клонирование данных можно забыть.
Ну конечно, если у тебя выборки не могут превышать пары сотен записей, то ради бога.
Alexander Panov (2005-08-31 09:03:00) [3]Piter © (31.08.05 0:42) [23]
твой пример неправильный тем, что вызываешь обработчик событие в доп. потоке, что чревато. Стараются делать VCL совместимое все.
Пример был не для того, чтобы его использовать напрямую.
Piter © (31.08.05 0:42) [23]
А вот насчет передачи Query через Synchronize тоже чревато - ибо юзер может и Open сделать, и ExecSQL и т.д.
Ты о чем? Какой юзер? Программу пишешь ты а не юзер.
Просмотрел всю ветку сначала, не нашел слова "юзер" ни в одном посте.
Карелин Артем (2005-08-31 05:36:00) [4]
ClientDataSet1.FieldDefs.Assign(IBQuery1.FieldDefs);
ClientDataSet1.CreateDataSet;
ClientDataSet1.Open;
IBQuery1.First;
while not(IBQuery1.Eof) do
begin
ClientDataSet1.Append;
for i:=0 to IBQuery1.FieldCount-1 do
begin
ClientDataSet1.Fields[i].Value:=IBQuery1.Fields[i].Value;
end;
ClientDataSet1.Post;
IBQuery1.Next;
end;//while
Fay (2005-08-31 03:44:00) [5]К Fay © (31.08.05 3:43) [24]
... в случае одного Connection-образного экземпляра для неск. потоков
Fay (2005-08-31 03:43:00) [6]2 Piter © (29.08.05 23:50)
При фетче легко можно получить что-нибудь типа "Connection is busy"
З.Ы.
Я не дружу с американским 8(
Piter (2005-08-31 00:42:00) [7]Alexander Panov © (30.08.05 23:45) [22]
твой пример неправильный тем, что вызываешь обработчик событие в доп. потоке, что чревато. Стараются делать VCL совместимое все.
А вот насчет передачи Query через Synchronize тоже чревато - ибо юзер может и Open сделать, и ExecSQL и т.д.
А с TFields особо ничего не сотворишь... пока мне так кажется...
Alexander Panov (2005-08-30 23:45:00) [8]Piter © (30.08.05 20:12) [19]
Видимо, единственный грамотный способ вернуть полученные данные в другой поток
Хм. видимо мой пример неправильный и TQuery в нем ни в какую нельзя использовать.
Piter (2005-08-30 21:02:00) [9]Карелин Артем © (30.08.05 20:33) [20]
А поток как долго будет после этого жить?
дык потос Syncronize вызывает - соответственно, замрет на это время
Карелин Артем © (30.08.05 20:33) [20]
Может в какой-нибудь набор данных в памяти скапировать данные?
а вот это интересно. Если перекопировать переданный Query.Fields в другой TFields - нормально будет?
Карелин Артем (2005-08-30 20:33:00) [10]
> Piter © (30.08.05 20:12) [19]
А поток как долго будет после этого жить? Может в какой-нибудь набор данных в памяти скапировать данные?
Piter (2005-08-30 20:12:00) [11]Piter © (30.08.05 17:46) [17]
Народ!
Вот что придумал. Итак, задаем запрос потоку, он соединяется с базой, выполняет запрос. А потом в Synchronize процедуре возвращает ссылку на Query.Fields - так подойдет?
Отвечаю сам себе - да, подойдет! Видимо, единственный грамотный способ вернуть полученные данные в другой поток
Карелин Артем (2005-08-30 19:29:00) [12]
> Val © (30.08.05 13:42) [10]
Вообще-то он прекращает выполнение запросов в этом случае. По крайней мере в моем софте.
Piter (2005-08-30 17:46:00) [13]isasa © (30.08.05 16:41) [16]
А ComObj используем
не понял. Кто ComObj использует?
Народ!
Вот что придумал. Итак, задаем запрос потоку, он соединяется с базой, выполняет запрос. А потом в Synchronize процедуре возвращает ссылку на Query.Fields - так подойдет?
Если Query создан в доп. потоке, то можно к Query.Fields обращаться в основном потоке для извлечения значения полей?
isasa (2005-08-30 16:41:00) [14]А ComObj используем.
Имеем(по умолчанию) - CoInitialize(),
надо - CoInitializeEx( COINIT_MULTITHREADED ), или хотя бы CoInitializeEx( COINIT_APARTMENTTHREADED )
Piter (2005-08-30 16:34:00) [15]теперь осталось разъяснить, причем здесь COM
isasa (2005-08-30 15:55:00) [16]Никто не вспомнил?
{ CoInitFlags determines the COM threading model of the application or current
thread. This bitflag value is passed to CoInitializeEx in ComServ initialization.
Assign COINIT_APARTMENTTHREADED or COINIT_MULTITHREADED to this variable before
Application.Initialize is called by the project source file to select a
threading model. Other CoInitializeEx flags (such as COINIT_SPEED_OVER_MEMORY)
can be OR'd in also. }
var
CoInitFlags: Integer = -1; // defaults to no threading model, call CoInitialize()
ANB (2005-08-30 14:21:00) [17]
> Anatoly Podgoretsky © (30.08.05 14:17) [12]
- ну, оракла может стать колом даже при снятии сессии, смотря что в ней гоняли, гы. Тут уже никакая асинхронка не поможет.
Anatoly Podgoretsky (2005-08-30 14:17:00) [18]Alexander Panov © (30.08.05 13:38) [9]
Хотелось бы, что бы от этого сервер не вставал колом, когда пьяный программист вдруг возьмем и грохнет все. Случаи известны.
ANB (2005-08-30 14:04:00) [19]Для асинхронки выход один (имхо) - уходить на специфичные для нужного сервера методы доступа. Для Oracle и MS SQL поддерживается асинхронка. Вывод длительных запросов в отдельный поток решает только проблему неподвисания интерфейса, но снять такой запрос будет проблематично. В ADO есть возможность организовать асинхронное выполнение без отдельных потоков, но, во первых, работает не всегда, во вторых - я все равно не нашел, как прервать такую операцию.
Val (2005-08-30 13:42:00) [20]не думаю. поэтому он спокойно колбасит себе свои запросы и далее.