Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.02.27;
Скачать: CL | DM;

Вниз

Запрос в потоке. Правильно пишу?   Найти похожие ветки 

 
12 ©   (2010-11-30 15:48) [0]

     
 TQ: ThQuery;
после прочтения Многопоточность - как это делается в Дельфи
решил применить к жизни.
Пишу
...
     TQ := ThQuery.Create(True);
     TQ.FreeOnTerminate := True;
     TQ.Q := AQuery;
     TQ.Resume;
....

где,
type
 ThQuery = class(TThread)
 private  
   FQ: TOraQuery;  
   function GetQ: TOraQuery;
   procedure SetQ(const Value: TOraQuery);
 protected
   procedure Execute; override;
 public
   property Q: TOraQuery read GetQ write SetQ;
 end;

implementation

procedure ThQuery.Execute;
begin
 Q.Open;
end;
function ThQuery.GetQ: TOraQuery;
begin
 Result := FQ;
end;
procedure ThQuery.SetQ(const Value: TOraQuery);
begin
 FQ := Value;
end;


 
12 ©   (2010-11-30 15:52) [1]

к чему - что-то не вижу разницы, притормаживает все равно.
Тесты на пару миллионах записях, fetchall = true


 
Engine ©   (2010-11-30 15:53) [2]

Неправильно, нет синхронизации между Q и FQ


 
Ega23 ©   (2010-11-30 15:54) [3]

А теперь навесь на данный экземпляр TOraQuery несколько обработчиков, прицепи DataSource и DBGrid.
И посмотри на результат.


 
12 ©   (2010-11-30 15:57) [4]

да?
что-то не уверен,

класс потока переписал так, остальное оставил

type
ThQuery = class(TThread)
protected
  procedure Execute; override;
public
  Q: TOraQuery;
end;

implementation

procedure ThQuery.Execute;
begin
Q.Open;
end


 
12 ©   (2010-11-30 15:59) [5]


> Ega23 ©   (30.11.10 15:54) [3]

не, наверное не так выразился.
По-идее, должно быть так: Нажал выполнить запрос - а форму в это время можно таскать, ресазить, она должна отвечать, словом.

Не отвечает все равно, с пол-секунды где-то


 
engine ©   (2010-11-30 16:01) [6]

хотя бы так, надо:

type
ThQuery = class(TThread)
private  
  FQ: TOraQuery;  
  CS: TCriticalSection;
  function GetQ: TOraQuery;
  procedure SetQ(const Value: TOraQuery);
protected
  procedure Execute; override;
public
  property Q: TOraQuery read GetQ write SetQ;
end;

implementation

procedure ThQuery.Execute;
begin
Q.Open;
end;
function ThQuery.GetQ: TOraQuery;
begin
EnterCriticalSection(CS);
Result := FQ;
LeaveCriticalsSection(CS);  
end;
procedure ThQuery.SetQ(const Value: TOraQuery);
begin
EnterCriticalSection(CS);
FQ := Value;
LeaveCriticalsSection(CS);
end;


ну и добавить InitializeCriticalSection/DeleteCriticalSection;


 
Игорь Шевченко ©   (2010-11-30 16:20) [7]


>  TQ: ThQuery;
> после прочтения Многопоточность - как это делается в Дельфи
> решил применить к жизни.
> Пишу


нафиг тебе это ?


 
Ega23 ©   (2010-11-30 16:22) [8]


> хотя бы так, надо:


И чего это даст???


 
engine ©   (2010-11-30 16:27) [9]

на сколько я понимаю, то в данном случае это защитит от одновременного обращения к полю FQ из основного и доп.потока, или я не прав? Поправьте тогда, самому интересна эта тема.


 
Ega23 ©   (2010-11-30 16:27) [10]

По-хорошему, надо делать как-то так:
1. Передать в тред ConnectionString
2. Передать в тред текст запроса
3. Создать соединение с БД, создать DataSet
4. Выполнить, дождаться конца
5. Отсигналить в основной тред, что данные зафетчены
6. Перегнать данные в основной тред (ну или передать сам НД, хотя я бы не стал)
7. Убиться.

При многих тредах имеет смысл организовать пул соединений. Хотя это от архитектуры зависит.


 
Ega23 ©   (2010-11-30 16:30) [11]


> на сколько я понимаю, то в данном случае это защитит от
> одновременного обращения к полю FQ из основного и доп.потока,
>  или я не прав? Поправьте тогда, самому интересна эта тема.


Да. Защитит. На момент операции присваивания. Но никак не защитит на момент выполнения самого треда.

Ну и в качестве ремарки: если есть EnterCriticalSection, то Leave - исключительно через try..finally. Иначе впоследствии намучаешься DeadLock-и ловить.


 
Ega23 ©   (2010-11-30 16:36) [12]

Тут подумал. Вообще не защитит. Ни от чего. Вообще бессмысленно.


 
engine ©   (2010-11-30 16:36) [13]


> Но никак не защитит на момент выполнения самого треда.
>

Точно, каюсь, был невнимателен. А за ремарку спасибо, об этом я не знал. Пошел править.


 
engine ©   (2010-11-30 16:38) [14]

а если так:
 EnterCriticalSection(CS)
 try
   FQ.Open;
 finally
   LeaveCriticalSection(CS);
 end;


 
Юрий Зотов ©   (2010-11-30 16:39) [15]


> Ega23 ©   (30.11.10 16:22) [8]

Только то, что во время выполнения длительного запроса у юзера не возникнет ощущения, что программа зависла.


 
engine ©   (2010-11-30 16:39) [16]

Или бессмысленно, т.к. работаем с ссылкой на объект, а не с самим объектом?


 
Юрий Зотов ©   (2010-11-30 16:41) [17]


> engine ©   (30.11.10 16:39) [16]

В Delphi (и не только) любой объект - это ссылка.


 
Ega23 ©   (2010-11-30 16:41) [18]


> Или бессмысленно, т.к. работаем с ссылкой на объект, а не
> с самим объектом?


Тут дело в другом. Нужно чтобы и стой стороны, ну, со стороны основного треда, доступ к FQ тоже через эту же крит-секцию был организован.


 
engine ©   (2010-11-30 16:43) [19]

тогда [14] должно быть правильно


 
Ega23 ©   (2010-11-30 16:44) [20]


> engine ©   (30.11.10 16:38) [14]
>
> а если так:


А что это даст? Это будет означать, что данный тред встал в крит-секцию и выполняет FQ.Open
при этом, если ссылка на этот FQ есть у кого-то другого, ничего не мешает этому "другому" сделать FQ.Free.
Ибо этот "другой" ничего про твою крит-секцию не знает и слюной на неё плевать хотел.


 
engine ©   (2010-11-30 16:46) [21]

как сделает? Он же через property к FQ обращается, а там защищено


 
Ega23 ©   (2010-11-30 16:53) [22]


> как сделает? Он же через property к FQ обращается, а там
> защищено


Да щаз.


type
ThQuery = class(TThread)
private  
  FQ: TOraQuery;  
  function GetQ: TOraQuery;
  procedure SetQ(const Value: TOraQuery);
protected
  procedure Execute; override;
public
  property Q: TOraQuery read GetQ write SetQ;
end;


В проперть-то его кто положил? Оно от сырости там завелось?

самый простой пример:
1. я создал экземпляр TOraQuery (в основном треде). Назовём Q1: TOraQuery.
2. я создал экземпляр ThQuery (в основном треде). Назовём Th1: ThQuery
3. я присвоил Th1.Q := Q1;
4. Отправил Th1.Resume
5. Th1 выполняется полчаса, например
6. через минуту я взял и вызвал Q1.Free.

Заметь, не Th1.Q.Free, а именно Q1.Free


 
engine ©   (2010-11-30 17:00) [23]

Согласен, изначально реализация была кривой. Хорошо, что у меня объекты, с которыми работает поток, создаются внутри потока.
Спасибо, за подробное объяснение.


 
12 ©   (2010-11-30 17:17) [24]

ща, поробую
и сам уже на листке порисовал-порисовал   -  надо, наверное, в потоке кверик создать
передавать пользователю только хотелось бы изящно - ссылку на область, которую будет трактовать как надо


 
Ega23 ©   (2010-11-30 17:23) [25]

Про Owner e Qwery не забывай. Либо разрушай самостоятельно.
Хотя стрёмный это путь. Не нравится чем-то. Чем - не могу сказать.


> передавать пользователю только хотелось бы изящно


SendMessage главному окну, LParam = Integer(Query)

соответственно, в главном окне Query = TOraQuery(Pointer(LParam))


 
12 ©   (2010-11-30 17:40) [26]


> SendMessage главному окну, LParam = Integer(Query)
> соответственно, в главном окне Query = TOraQuery(Pointer(LParam))

Это понятно, это давно использую
Но, тут в потоке. Придет ссылка - а поток разрушен, вдруг?
Надо гарантировать, что не разрушится
Ща, еще порисую..
Спасибо, Олег.

Просто первый раз серьезно решил заняться. На уровне сдать лабу - сдавал, но не пригодилось никогда еще :)

Кстати,
2 ИШ


> нафиг тебе это ?

Программирование - то? :)
Да как сказать..

Вот Вы большой и умный и Мастер даже..
А все норовите обидеть да задеть. Мне то пофиг, меня так обижали - ой-ёй

И получается, что просто Вас читать даже не хочется - ну чего нового Вы расскажете - ничего. Только сделаете очередную попытку оскорбить

А от Мастера ожидается как-бы посыл хоть и на 3 буквы (я про www, не подумайте :)) но чтоб мысли родились в голове.
от посыла то, от этого, от мастерского :)

Ну вот как-то так.


 
Engine ©   (2010-11-30 17:47) [27]

Может тогда не использовать FreeOnTerminate :=true? Разрушать только тогда, когда уж точно не нужен больше.


 
Ega23 ©   (2010-11-30 17:49) [28]


> Но, тут в потоке. Придет ссылка - а поток разрушен, вдруг?
>
> Надо гарантировать, что не разрушится


Блин. Ты свой Query в потоке создал, но не разрушил. Разрушать будет главный поток.
Дальше, из потока ты сделал SendMessage. В параметре передал ссылку на созданный Query. Пока обработчик SendMessage не отработает - поток будет ждать. Соответственно, там ссылку из параметра сохранил и сделал все телодвижения.
Поток дождался и убился. При этом деструктор Query не вызывает.


 
Ega23 ©   (2010-11-30 17:53) [29]

Но мне эта схема всё равно не нравится. Используй TClientDataSet, что-ли...


 
engine ©   (2010-11-30 18:07) [30]

Вот еще интересный вариант:
http://www.delphikingdom.ru/asp/viewitem.asp?catalogid=1355

Интересно, что о нем думают мастера?


 
Игорь Шевченко ©   (2010-11-30 18:22) [31]


> Программирование - то? :)


не, дваркование запроса в отдельном потоке влэндишым способом.


> А все норовите обидеть да задеть.


А теперь подумай - а нафиг мне это ?


 
MsGuns ©   (2010-11-30 20:30) [32]

1. Не имеет смысла запускать в потоке то, чем нет возможности управлять. Например, запрос, который нельзя прервать. А если пресловутый "кверик" можно "снять" (не знаю как в уракле, а в АДО есть т.н. асинхронный режим, позволяющий не ждать завершения выполнения запроса)

2. Если запрос управляем, то где код, реализующий проверку на Terminate потока и соответственно "снимающий" кверик ?

3. На время выполнения "фоновых" запросов никоим образом не связывать их с визуальными компонентами - только по завершению.

4. Если результаты "фонового" запроса должны отображаться, то сам запрос (TXXXQuery) должен быть создан в основном потоке, а выполняться во вторичном, куда собственно и следует передавать указатель на квери при создании и запуске потока. Это позволит потоку благополучно помереть после завершения, а результатам - остаться для дальнейшего использования

5. Критические секции нужны лишь на создание объектов, но никак ни на сам ход выполнения запроса - для этого всего лишь нужно получать и обрабатывать сообщения сервера в "обычном", некритичном коде. Что легко делвется в "управляемом" запросе.

Все ИМХО


 
Игорь Шевченко ©   (2010-11-30 23:14) [33]

по сабжу - делал когда-то по дури заполнение грида отдельным потоком, типа данные бегают себе асинхронно, граждане довольные расходятся по домам и все такое.

Красиво, но нахрен не нужно.


 
Ega23 ©   (2010-12-01 00:55) [34]


> MsGuns ©   (30.11.10 20:30) [32]


Пункты 4 и 5 - чушь.
Также сильно подозреваю, что 1 и 2 - тоже. Под рукой справки нет.


 
Anatoly Podgoretsky ©   (2010-12-01 09:29) [35]

> Ega23  (01.12.2010 00:55:34)  [34]

Пункт 1 не чушь. Скажи что делать если запущен очень длительный запрос и его
надо прекратить нормально, а не аварийно?


 
Ega23 ©   (2010-12-01 09:58) [36]


> Пункт 1 не чушь.


Возможно. Я про асинхронный режим на память не силён, надо справку читать.


 
12 ©   (2010-12-01 10:37) [37]

Все, не тормозит вообще
> 1. Передать в тред ConnectionString
> 2. Передать в тред текст запроса
> 3. Создать соединение с БД, создать DataSet
> 4. Выполнить, дождаться конца
> 5. Отсигналить в основной тред, что данные зафетчены
> 6. передать сам НД через мессадж
И убиваю поток, когда пользователь новый запрос просит выполнить


> Красиво, но нахрен не нужно.

а боюсь, что так и получится
Но так, чисто для себя, чтоб на душе было комфортно :)


 
12 ©   (2010-12-01 10:40) [38]


> И убиваю поток, когда пользователь новый запрос просит выполнить

Да, и не даю выпонять еще один, пока не выполнился первый - иначе БД положат
А нафига все это - именно как ЮЗ сказал - чтоб у юзера не было сомнений, программа ли зависла или запрос долгий.


 
Ega23 ©   (2010-12-01 10:49) [39]


>  чтоб у юзера не было сомнений, программа ли зависла или
> запрос долгий.


Screen.Cursor := crSQLWait;
try
 DataSet.Open;
finally
 Screen.Cursor := crDefault;
ebd;


:)


 
Ega23 ©   (2010-12-01 10:51) [40]


> И убиваю поток, когда пользователь новый запрос просит выполнить


Зачем? Ставь его в Suspend. Соединение создано, НД создан.


 
12 ©   (2010-12-01 11:02) [41]


> Screen.Cursor := crSQLWait;
> try
>  DataSet.Open;
> finally
>  Screen.Cursor := crDefault;
> ebd;

так и было до потока
но тогда пользователь в другое МДИ окно не мог переключится и поредактировать что-то, пока запрос идет.


 
Ega23 ©   (2010-12-01 11:04) [42]

А, ну это другое дело.


 
12 ©   (2010-12-01 11:05) [43]


> ачем? Ставь его в Suspend. Соединение создано, НД создан.

Логично, ща..


 
Ega23 ©   (2010-12-01 11:19) [44]

На самом деле я бы пул соединений сделал. Т.е. есть класс потока, есть класс - список этих потоков. У класса-списка есть свойство, типа MaxConnections. Также этот класс-список знает, какие потоки у него в данный момент раюотают, а какие - простаивают.
Передал туда текст запроса, он пробежался по списку. если нашёл свободный - передал запрос ему. Если свободных не нашёл - создал новый (если Count < MaxConnections). Если свободных нет и Count = MaxConnections - ждём, пока кто-то освободится.


 
12 ©   (2010-12-01 11:23) [45]


> Ega23 ©   (01.12.10 11:19) [44]

Больно сурьезно
если будет надобность - надо будет попробавать нечто подобное сделать


 
Игорь Шевченко ©   (2010-12-01 11:26) [46]


> но тогда пользователь в другое МДИ окно не мог переключится
> и поредактировать что-то, пока запрос идет.


Вот это и есть САМОЕ ГЛАВНОЕ ЗАБЛУЖДЕНИЕ.

Пользователь, который открывает окно с данными, не будет никуда переключаться и , тем более, что-то редактировать, а будет тупо ждать, пока нужные данные не появятся или пойдет курить/пить чай/трепаться с коллегами.


 
Ega23 ©   (2010-12-01 11:27) [47]


> Больно сурьезно


В целом именно так и делается. Таким образом можешь самостоятельно нагрузкой на БД рулить.


 
Ega23 ©   (2010-12-01 11:28) [48]


> Вот это и есть САМОЕ ГЛАВНОЕ ЗАБЛУЖДЕНИЕ.


ИМХО, +1.
Юзер скорее на "Косынку" какую-нибудь переключится.


 
Anatoly Podgoretsky ©   (2010-12-01 13:34) [49]


> 12 ©   (01.12.10 10:40) [38]

Анимация


 
Anatoly Podgoretsky ©   (2010-12-01 13:35) [50]

> 12  (01.12.2010 10:40:38)  [38]

Ассинхронные запросы. Но надо уметь с ними работать. Ассинхронность, веэде,
не всем подвластна.


 
Anatoly Podgoretsky ©   (2010-12-01 13:37) [51]


> Юзер скорее на "Косынку" какую-нибудь переключится.

Боятся. Предпочитают подождать.


 
MsGuns ©   (2010-12-01 20:46) [52]

>Ega23 ©   (01.12.10 11:28) [48]
>Юзер скорее на "Косынку" какую-нибудь переключится.

Далеко не всегда. "Фоновость" полезна в ситуациях, когда надо много вводить и параллельно формировать отчеты - в этом случае юзеру (бухгалтеру например) не до "косынок", а многопоточность весьма уместна и реально в разы повышает эффективность работы с прогой.

И вообще чего тут рассуждать - берем любую профи-прогу (тот же почтовый клиент, торрент и многое другое) и смотрим как реализовано, в т.ч. интерфейс - и делаем так же


 
Leonid Troyanovsky ©   (2010-12-01 22:42) [53]


> MsGuns ©   (01.12.10 20:46) [52]

>  а многопоточность весьма уместна и реально в разы повышает
> эффективность работы с прогой.

Повышение эффективности многопоточности можно связать,
например, с ростом количества процессоров в системе, хотя,
уж вовсе не в разы.

--
Regards, LVT.


 
Ega23 ©   (2010-12-01 23:42) [54]


>  берем любую профи-прогу (тот же почтовый клиент, торрент
> и многое другое) и смотрим как реализовано, в т.ч. интерфейс
> - и делаем так же


Открыл m-Torrent и Thunderbird. Посмотрел на интерфейс. MDI не увидел.
Что я делаю не так?


 
MsGuns ©   (2010-12-02 11:22) [55]

А кто говорил про МДИ ?


 
MsGuns ©   (2010-12-02 11:25) [56]

>Leonid Troyanovsky ©   (01.12.10 22:42) [53]
>Повышение эффективности многопоточности можно связать,
>например, с ростом количества процессоров в системе, хотя,
>уж вовсе не в разы.

Имелось в виду, что одну и ту же работу бухгалтер (экономист, технолог, менеджер по продажам и т.д.) делает с "многопоточной" программой в два-три раза быстрее, чем с программой, работающей "как обычно".
Проверено многократно.


 
Ega23 ©   (2010-12-02 11:55) [57]


> А кто говорил про МДИ ?


Влад говорил.


> Проверено многократно.


С этим никто не спорит. "Всякому овощу...", как ИШ любит говорить.
Вот только всё равно в [32] пункты 4 и 5 - чушь. :)


 
Игорь Шевченко ©   (2010-12-02 16:32) [58]


> Имелось в виду, что одну и ту же работу бухгалтер (экономист,
>  технолог, менеджер по продажам и т.д.) делает с "многопоточной"
> программой в два-три раза быстрее, чем с программой, работающей
> "как обычно".
> Проверено многократно.


"Вы, сударь, ерунду говорите. И хуже всего то, что говорите безапеляционно и уверенно"


 
MsGuns ©   (2010-12-02 18:46) [59]

>Ega23 ©   (02.12.10 11:55) [57]
>Вот только всё равно в [32] пункты 4 и 5 - чушь. :)

>Игорь Шевченко ©   (02.12.10 16:32) [58]
>"Вы, сударь, ерунду говорите. И хуже всего то, что говорите >безапеляционно и уверенно"

Аргументы, как всегда, убойные.
Уполз в кусты помирать :)


 
Ega23 ©   (2010-12-02 19:21) [60]


> Аргументы, как всегда, убойные.


Вы хочите песен?
Их есть у меня

4. Если результаты "фонового" запроса должны отображаться, то сам запрос (TXXXQuery) должен быть создан в основном потоке, а выполняться во вторичном, куда собственно и следует передавать указатель на квери при создании и запуске потока. Это позволит потоку благополучно помереть после завершения, а результатам - остаться для дальнейшего использования


Кто сказал, что "сам TXXXQuery должен быть создан" ...
Что вообще такое класс TThread, тебе известно? Как запустить код на исполнение в отдельном треде без данного класса? Кто там, где и когда помирает?
Есть мнение, что ты не очень разбираешься в этой кухне, ничего личного.

5. Критические секции нужны лишь на создание объектов, но никак ни на сам ход выполнения запроса - для этого всего лишь нужно получать и обрабатывать сообщения сервера в "обычном", некритичном коде. Что легко делвется в "управляемом" запросе.

Критические секции нужны для исключения одновременного доступа с изменением к данным.
Если у тебя доступ - строго чтение, то пофигу. Тебя же не напрягает использование одной и той же константы из разных тредов? А вот если я читаю данные, а кто-то начал их модифицировать, тогда может случиться "ой". А может и нет, это как повезёт.

З.Ы. рекомендую внимательно посмотреть на код TThread.


 
MsGuns ©   (2010-12-02 19:50) [61]

>Ega23 ©   (02.12.10 19:21) [60]

Мухи и котлеты :)
Если тебе нравится считать, что я не разбираюсь, то на здоровье :)


 
Ega23 ©   (2010-12-03 11:33) [62]


> Если тебе нравится считать, что я не разбираюсь, то на здоровье


Серёж, мы же не первый год на форуме. Да и не нубы, вроде как. И "за базар" отвечать должны тоже не так, как нубы.
Так что давай, аргументируй. Почему "TxxxQuery надо создавать в главном потоке" и почему "крит.секция нужна только на момент создания объекта".
Как говорится, TITS or GTFO


 
Юрий Зотов ©   (2010-12-04 23:20) [63]

> Ega23 ©   (03.12.10 11:33) [62]

> Почему "TxxxQuery надо создавать в главном потоке"

Если кверик не убивается при уничтожении потока, в котором он был открыт, то его данные сохраняются. Создавать его, конечно, можно где угодно, но логично поручить это главному потоку.


 
MsGuns ©   (2010-12-05 15:21) [64]

>Ega23 ©   (03.12.10 11:33) [62]
>Серёж, мы же не первый год на форуме. Да и не нубы, вроде как.

Не нубы, но иногда хамим :)

>И "за базар" отвечать должны тоже не так, как нубы.
>Почему "TxxxQuery надо создавать в главном потоке"

Я писал там, что если данные, полученные квери, нужны для отображения. Т.е. поток уже не нужен (он выполнился, "скачав" данные с сервера на клиент, более он не нужен, поэтому логично его прибить). Если квери создать в самом потоке, то по завершении запроса нужно либо куда-то в осн.поток эти данные передать (скопировать), либо не убивать поток до тех пор, пока данные запроса не станут ненужными. Короче - геморрой да и только.
Много проще создать и подготовить запрос  и готовый передать (точнее указатель на него - это чтоб ты меня опять в чем-нить не начал обвинять :) потоку. Он выполнить запрос, "отследив" результат, и благополучно помрет.

>и почему "крит.секция нужна только на момент создания объекта".

Опять-таки речь шла о кверике. Для его создания критическая секция нужна, ясен красень. А вот выполнение его в асинхронном режиме в трай и нафиг ну нужно засовывать (Хотя бы потому, что само АДО эти самые траи всунет куда надо), а просто "ловить" состояние запроса в цикле и, получив сигнал о завершении (ошибочном или нормальном), обработать его или передать гл.потоку.

Я давал этот "совет" (кстати, снабдив его имхой, т.е. не навязывал и не считал единственно верным) потому, что сам так делал многократно и все надежно фунциклировало: юзер весело шарился мышой или клацал клавой, а выборка (выборки) спокойно себе шла в фоне, о чем гденить в статусстроке светался соотв.текстик :)


 
Ega23 ©   (2010-12-05 17:19) [65]


> Создавать его, конечно, можно где угодно, но логично поручить
> это главному потоку.


Ганс писал:
Если результаты "фонового" запроса должны отображаться, то сам запрос (TXXXQuery) должен быть создан в основном потоке, а выполняться во вторичном, куда собственно и следует передавать указатель на квери при создании и запуске потока.

Собственно, я и доковырялся до должен. Ибо он может быть создан где угодно.


 
Ega23 ©   (2010-12-05 17:24) [66]


>  Если квери создать в самом потоке, то по завершении запроса
> нужно либо куда-то в осн.поток эти данные передать (скопировать),
>  либо не убивать поток до тех пор, пока данные запроса не
> станут ненужными.


Дааааа?
Объясни мне, что мешает создать кверь в дополнительном треде, выполнить, передать на неё указатель основному треду, после чего убить дополнительный тред?


> Для его создания критическая секция нужна, ясен красень.


Зачем она нужна??? Да ещё и на создание? Для чего????


 
Юрий Зотов ©   (2010-12-05 22:36) [67]

Are binary programmers deathless?...
:o)


 
MsGuns ©   (2010-12-06 02:02) [68]

>Ega23 ©   (05.12.10 17:24) [66]
>Объясни мне, что мешает создать кверь в дополнительном треде, >выполнить, передать на неё указатель основному треду, после чего убить >дополнительный тред?

Видишь ли, я приучен к тому, что каждый созданный объект должен помирая, уничтожить все, что он создал для своей работы. Т.е. если кверик был создан в нити, то нить и должна его прибить погибая. Поэтому в осн.поток указатель-то я передать могу, но только на что он будет указывать ? Или же нить "поручит" убийство потоку основному ? А вот такие программы я в корзине видел, а программистов, пишущих такое - в гробу в белых тапках,
Кроме того, зачем грузить в нить всякую требуху для того кверика. Например, параметры соединения, текст запроса и прочие разности, о которых "знает" логика осн.программы, но вовсе не обязан знать поток, основная функция которого в данном случае - всего лишь распараллеливание.

>> Для его создания критическая секция нужна, ясен красень.
>Зачем она нужна??? Да ещё и на создание? Для чего????

Для того же, для чего нужны критические секции для любого кода, в котором могут быть независимые от программы ошибки. Например, при выделении ресурсов системой. Опять же делаю как завещали умные люди :)

ЗЫ. Похоже, ты, Олежа, просто уперся и не хочешь отступать. Поэтому спор дальнейший бессмысленен. На что я и намекал в [61] ;)


 
Ega23 ©   (2010-12-06 11:08) [69]


> Т.е. если кверик был создан в нити, то нить и должна его
> прибить погибая.


У тебя каша в голове. Читай внимательно MSDN по CreateThread
Если ты мне там хоть один класс покажешь - я прилюдно буду извиняться.


> Кроме того, зачем грузить в нить всякую требуху для того
> кверика. Например, параметры соединения, текст запроса и
> прочие разности, о которых "знает" логика осн.программы,
>  но вовсе не обязан знать поток, основная функция которого
> в данном случае - всего лишь распараллеливание.


Один тред - один коннект. Иначе грабли, рано или поздно.


> Для того же, для чего нужны критические секции для любого
> кода, в котором могут быть независимые от программы ошибки.
>  Например, при выделении ресурсов системой. Опять же делаю
> как завещали умные люди :)


Какие ресурсы? Какие независимые от программы ошибки? Крит.секция - объект синхронизации, не более того. Какая синхронизация может на создании происходить? Что за бред?


 
Ega23 ©   (2010-12-06 11:28) [70]


> ЗЫ. Похоже, ты, Олежа, просто уперся и не хочешь отступать.
>  Поэтому спор дальнейший бессмысленен.


Да если бы это в потрепаловке было, или там в базах - я бы давно слюной плюнул на дремучесть, да и дело с концом. ССЗБ, можешь писать как вздумается.
Но в начинающих хрень постить - это некузяво.


 
MsGuns ©   (2010-12-06 16:51) [71]

>Ega23 ©   (06.12.10 11:08) [69]
>У тебя каша в голове. Читай внимательно MSDN по CreateThread

Разберись сначала со своей

>Один тред - один коннект. Иначе грабли, рано или поздно.

А вот это чушь полная

>Какие ресурсы? Какие независимые от программы ошибки? Крит.секция - >объект синхронизации, не более того. Какая синхронизация может на >создании происходить? Что за бред?

Я ж говорю, мухи и котлеты. Крит.секция = объект синхронизации ?
И причем здесь вообще синхронизация - я про нее хоть заикнулся ?

>Да если бы это в потрепаловке было, или там в базах - я бы давно слюной >плюнул на дремучесть, да и дело с концом.

Не даем себе труд хотя бы элементарно въехать в смысл того, что говорят, зато продолжаем хамить ?  На здоровье, но без меня.


 
Ega23 ©   (2010-12-06 16:59) [72]


>  Крит.секция = объект синхронизации ?


А что это, по-твоему?


> И причем здесь вообще синхронизация - я про нее хоть заикнулся?


Дык и я о том же, синхронизация не нужна, однако "крит.секция нужна, ясен пень". Может таки RTFM пора?


> Не даем себе труд хотя бы элементарно въехать в смысл того,
>  что говорят


Искренне пытаюсь уже несколько дней это сделать. Почему создавать кверь я должен в основном потоке, почему я должен использовать одно соединение, а также нафига нужна крит.секция в вышестоящем примере - я так и не понял.


> На здоровье, но без меня.

Понятно. Т.е. слив засчитан, да?


 
han_malign   (2010-12-06 18:21) [73]


> (TXXXQuery) должен быть создан в основном потоке, а выполняться во вторичном

- если это OLE провайдер, и интерфейс создается в STA(по умолчанию, см. comobj), то доп. поток не поможет - один фиг все будет маршалироваться в контекст основного потока... Другое дело, что большинство провайдеров и так асинхронные и вынос явного ожидания завершения запроса в другой поток - это просто чесание левого уха правой пяткой...


 
Ega23 ©   (2010-12-06 19:58) [74]


> то доп. поток не поможет - один фиг все будет маршалироваться
> в контекст основного потока...


CoInitialize ?


 
Вариант   (2010-12-07 06:58) [75]


> Ega23 ©   (06.12.10 19:58) [74]


> CoInitialize ?

Кстати тема интересная. Я не уверен в своем правильном понимании этой темы. Поэтому разовью, а кто хорошо знает пусть поправит. Создав COM объект в потоке имеющий апартамент STA (в дельфи основной поток по умолчанию) мы вызывая методы объекта объекта даже в другом потоке, все равно переадресуем вызов этих методов (маршалируем) в поток создавший этот объект. То есть имеем ситуацию
> han_malign   (06.12.10 18:21) [73]
И Coinitialize в другом потоке (создаем апартамент STA для вызвавшего потока) не поможет, если COM объект был создан в другом. Ибо методы его в тихую будут вызваны в создавшем его потоке.....


 
Ega23 ©   (2010-12-07 07:25) [76]


> Ибо методы его в тихую будут вызваны в создавшем его потоке.
> ....

Это уже интересно. Ща обдумаем.


 
han_malign   (2010-12-07 12:57) [77]


> CoInitialize ?

- CoInitializeEx(nil,COINIT_MULTITHREADED)

> Ибо методы его в тихую будут вызваны в создавшем его потоке.....

- все чуть запутанней: http://www.compdoc.ru/prog/cpp/com/ch5/ch52.shtml



Страницы: 1 2 вся ветка

Текущий архив: 2011.02.27;
Скачать: CL | DM;

Наверх




Память: 0.71 MB
Время: 0.011 c
2-1291283179
Великий
2010-12-02 12:46
2011.02.27
Посимвольное считывание из Edit а


15-1290093745
БарЛог
2010-11-18 18:22
2011.02.27
Программа для создания меню запуска


2-1291306769
Чайник
2010-12-02 19:19
2011.02.27
Вставка в TStringGrid через буфер обмена


2-1291285177
Свободный художник
2010-12-02 13:19
2011.02.27
работа с форматом dwg, конертация bmp в dwg и обратно


15-1289660689
Медвежонок Пятачок
2010-11-13 18:04
2011.02.27
некоторые художники утверждают ...