Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2007.01.21;
Скачать: [xml.tar.bz2];

Вниз

Теоритический вопрос про потоки и контекст   Найти похожие ветки 

 
Anatoly Podgoretsky ©   (2006-11-23 14:28) [0]

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

Thead = TThead
 SL: TStringList
end;

TThead.Create;
Begin
 SL := TStringList.Create;
end;

TThead.Execute;
Begin
 SL := TStringList.Create;
end;

TThead.Execute;
var
 SL: TStringList;
Begin
 SL := TStringList.Create;
end;

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

TThead.Execute;
Begin
 SL := SL[0]
end;

С третьем случае все одназначно, в контексте потока, а первые два?


 
Сергей М. ©   (2006-11-23 14:31) [1]

Толя, и это ТЫ вопрошаешь  ?!!!!!

да не поверю) ...

Провокация ?!


 
Джо ©   (2006-11-23 14:32) [2]

> SL := SL[0]

Анатолий, ведь это даже не скомпилируется.


 
clickmaker ©   (2006-11-23 14:33) [3]


> SL := SL[0]

а что это за загадочная строка?


 
Anatoly Podgoretsky ©   (2006-11-23 14:41) [4]

> Сергей М.  (23.11.2006 14:31:01)  [1]

А что простой вопрос задал, так быстро переместим его в Начинающие.
Знал бы ты какие ответы на это вопрос я слышал :-)


 
clickmaker ©   (2006-11-23 14:43) [5]


> Знал бы ты какие ответы на это вопрос я слышал

все кроме [2] ? ))


 
Anatoly Podgoretsky ©   (2006-11-23 14:44) [6]

> Джо  (23.11.2006 14:32:02)  [2]

Конечно не скомпилируется, я же предупредил. Если не понятен сокращеный код, то вот пояснение

1. SL расколожен внутри класса, создается в контексте главного потока (Create)
2. SL расколожен внутри класса, создается в Execute
3. SL расколожен внутри Execute, создается в Execute, доступ в контексте потока

Вопрос такой, в контексте какого потока будет доступ в Execute для  вариантов 1. и 2.
C третьим все ясно.


 
Anatoly Podgoretsky ©   (2006-11-23 14:44) [7]

> clickmaker  (23.11.2006 14:33:03)  [3]

Китайская очепятка

S := SL[0]


 
Сергей М. ©   (2006-11-23 14:45) [8]


> Знал бы ты какие ответы на это вопрос я слышал


Да уж знаю)... Поверь уж)


 
Anatoly Podgoretsky ©   (2006-11-23 14:57) [9]

> Сергей М.  (23.11.2006 14:45:08)  [8]

Ну так кто ни будь обладает достоверной информацией?
Или хотя бы не достоверной информацией, но с обоснованием.


 
clickmaker ©   (2006-11-23 15:03) [10]


> хотя бы не достоверной информацией, но с обоснованием

вот этот подход мне по душе. "Ответ неверный, но интересный", так? ))


 
Джо ©   (2006-11-23 15:05) [11]

> [6] Anatoly Podgoretsky ©   (23.11.06 14:44)
> > Джо  (23.11.2006 14:32:02)  [2]
>
> Конечно не скомпилируется, я же предупредил. Если не понятен
> сокращеный код, то вот пояснение
>
> 1. SL расколожен внутри класса, создается в контексте главного
> потока (Create)
> 2. SL расколожен внутри класса, создается в Execute
> 3. SL расколожен внутри Execute, создается в Execute, доступ
> в контексте потока

Все три — будут выполнятся в контексте потока (того, в котором Execute). А почему оно должно выполняться в каком-то другом контексте?


 
MBo ©   (2006-11-23 15:07) [12]

Эксперимент показал (окно Thread Status в BDS), что для всех случаев - в доп. потоке

 TT = class(TThread)
   SL: TStringList;
   constructor Create;
   procedure Execute; override;
 end;

procedure TForm16.Button1Click(Sender: TObject);
begin
 T:= TT.Create; //breakpoint 1
end;

{ TT }

constructor TT.Create;
begin
 inherited Create(True);
 SL := TStringList.Create;
 Resume;
end;

procedure TT.Execute;
var
 S: string;
//  SL: TStringList;
begin
//  SL := TStringList.Create;
 SL.Add("Yeah");
 SL.Add("Ndfg");
 s:= SL[0];  // breakpoint 2
 SendMessage(Form16.Handle, WM_USER, 0, Integer(s));
 SL.Free;
end;


 
Anatoly Podgoretsky ©   (2006-11-23 15:15) [13]

> clickmaker  (23.11.2006 15:03:10)  [10]

Неправильно, я рассмотрю обоснования или приму их или отвергну.


 
Anatoly Podgoretsky ©   (2006-11-23 15:18) [14]

> Джо  (23.11.2006 15:05:11)  [11]

Франсуа Пьетте сказал, что выполняться будет в контексте того потока, где создан объект и посоветовал все переместить в Execute - это помогло, но это мне не очень подходит, для простых систем еще ни чего, а для сложных с разными методами и процедурами не очень, поскольку переменные локальны для Execute, а не для объекта. Пока у меня реализовано по его рекомендации, но я думаю об варианте 1 и 2

Плохо, что пока никто не подошел, кто это достоверно знает.


 
Anatoly Podgoretsky ©   (2006-11-23 15:22) [15]

> MBo  (23.11.2006 15:07:12)  [12]

Вот это уже конкретнее, но для его компонентов (ICS), пока я не перенес SL в Execute это не работало. Вожможно это особенность его компонент. Но его слова "не важно где используется, выполняется (используется) в контексте того потока где создано". Метод Create выполняется в контексте главного потока.

Вот меня сомнения и мучают.


 
Eraser ©   (2006-11-23 15:29) [16]

> [15] Anatoly Podgoretsky ©   (23.11.06 15:22)

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


 
Джо ©   (2006-11-23 15:30) [17]

> [14] Anatoly Podgoretsky ©   (23.11.06 15:18)
> > Джо  (23.11.2006 15:05:11)  [11]
>
> Франсуа Пьетте сказал, что выполняться будет в контексте
> того потока, где создан объект

Странное, однако мнение. Где ссылка на объект хранится — какая, собственно, разница?
Еще понятно было бы, если бы в TStringList.Get какие-то были манипуляции для "переключения" контекстов, но ведь их там нет.


 
Anatoly Podgoretsky ©   (2006-11-23 15:38) [18]

> Eraser  (23.11.2006 15:29:16)  [16]

Как ты это представляешь, создавать самого себя не создав самого себя.
И речь шла не про его компоненты, а про вообще компоненты.


 
Anatoly Podgoretsky ©   (2006-11-23 15:40) [19]

> Джо  (23.11.2006 15:30:17)  [17]

TStringList приведен только для примера, кроме него еще есть следующие компоненты - THttpCli и АДО  компоненты.


 
Джо ©   (2006-11-23 15:42) [20]

> [19] Anatoly Podgoretsky ©   (23.11.06 15:40)
> > Джо  (23.11.2006 15:30:17)  [17]
>
> TStringList приведен только для примера, кроме него еще
> есть следующие компоненты - THttpCli и АДО  компоненты.

Ну, тогда и нужно смотреть их методы, на предмет наличия в них всяких "выкрутасов", если таковые имеются :)


 
Anatoly Podgoretsky ©   (2006-11-23 15:57) [21]

> Джо  (23.11.2006 15:42:20)  [20]

Да я проблемы обойду, не это интересует, а первые два слова темы.


 
Джо ©   (2006-11-23 15:58) [22]

> [21] Anatoly Podgoretsky ©   (23.11.06 15:57)
> Да я проблемы обойду, не это интересует, а первые два слова
> темы.

Какие именно: "Теоритический вопрос" или "Интересует следующая"? :)


 
MBo ©   (2006-11-23 16:02) [23]

>Где ссылка на объект хранится — какая, собственно, разница?

Интересно, что в моем примере, если вывести адрес (IntToHex(Integer(@SL),8)) локальной переменной главного потока (стек главного потока уменьшен до предела), StringList-а, созданного в Thread.Create, и локального для Execute StringList, то получается:
0006F520 009BDD18 003FFF60

Сами объекты, конечно, лежат в общей куче, и адреса их близкие
IntToHex(Integer(SL),8)
009BDCD8 009A0E40 009A0E00


 
Anatoly Podgoretsky ©   (2006-11-23 16:25) [24]

> MBo  (23.11.2006 16:02:23)  [23]

Мой здравый смысл подсказывает, что в контексте потока, но автор утверждает обратное, вот поэтому я и озаботился. Сейчас у меня реализовано по его рекомендации, в Execute, но я сейчас делаю рефакторинг с резким увеличением производительности и одновременно возрастает сложность, то варианты 1 и 2 меня очень интересуют, особенно один. Тогда программа очень сильно упращается и становится более управляемой. Я хочу большинство переменных перенести в модуль данных, создавать его в Create при создании потока и не беспокоиться об уничтожении. Каждый поток будет иметь свой модуль данных и тоже относится и к соединениям, каждое клиентское соединение будет иметь свой модуль данных.
Раннии эксперименты меня заставили перенести переменные из определения модуля в метод Execute.
После этого все стало стабильно, но не удобно. Это были следующие компоненты THttpCli, TAbsTable и TSringList.

Сейчас я перехожу вместо TAbsTable на АДО компоненты

Но меня интересует не практический вопрос, а теоритический


 
Anatoly Podgoretsky ©   (2006-11-23 16:25) [25]

> Джо  (23.11.2006 15:58:22)  [22]

Вопрос начинается со слов Теоритический вопрос


 
Джо ©   (2006-11-23 16:29) [26]

Ну, тогда для начала, Анатолий, попробуйте теоретически показать, отчего бы этому коду выполняться в ином потоке? Ведь очевидно же (я допускаю, что ошибочно) считать, что, раз никаких телодвижений для переключения контекста не делается, то и само-собой ничего не произойдет.


 
Eraser ©   (2006-11-23 16:32) [27]

> [24] Anatoly Podgoretsky ©   (23.11.06 16:25)


> Но меня интересует не практический вопрос, а теоритический

1. то что находится в ф-ции Execute по определению выполняется в доп. потоке. Вот и вся теория )

2. где вызывать конструктор? для TSringList могу ответить - все равно где.
а вот для сетевых или, что вероятнее БД компонентов разница може быть, но тут уж нужно смотреть реализацию самих компонентов.


 
Anatoly Podgoretsky ©   (2006-11-23 17:03) [28]

> Джо  (23.11.2006 16:29:26)  [26]

Я уже сказал, что моя логика протестует, автор утверждает обратное. Подтверждения ни тому ни другому по этому вопросу мне не встречалось.
Вопрос я вроде четко поставил, что именно интересует и в каком контесте, допольнительные уточнения тоже сделал.


 
Джо ©   (2006-11-23 17:05) [29]

> [28] Anatoly Podgoretsky ©   (23.11.06 17:03)
> > Джо  (23.11.2006 16:29:26)  [26]
>
> Я уже сказал, что моя логика протестует, автор утверждает
> обратное.

Анатолий, а не могли бы вы привести полную цитату, да еще и с контекстом? Возможно, неверный перевод, да мало ли что.


 
Anatoly Podgoretsky ©   (2006-11-23 17:06) [30]

> Eraser  (23.11.2006 16:32:27)  [27]

Если посмотреть на вариант 1 и 2, то там находится не в Execute и главный Сreate выполняется в контексте главного потока. Второй вариант я создаю в Execute, но сама переменная создана в контексте главного потока. Автор утверждает, что первостепенным явлется в контексте какого потока создается, а не в контексте какого используется.

Вот об этом и есть вопрос.
Моя логика с этим не соглашается.
Поведение показывает, что моя логика неверная.


 
Eraser ©   (2006-11-23 17:19) [31]

> [30] Anatoly Podgoretsky ©   (23.11.06 17:06)


> Если посмотреть на вариант 1 и 2, то там находится не в
> Execute и главный Сreate выполняется в контексте главного
> потока.

правильно, но, к примеру для TStringList, как и для 99% компонетов это нормально.

> Второй вариант я создаю в Execute, но сама переменная создана
> в контексте главного потока. Автор утверждает

я тут вижу противоречие :)

> Моя логика с этим не соглашается.
> Поведение показывает, что моя логика неверная.

а можно пример, уж очень заинтриговали )


 
Romkin ©   (2006-11-23 17:31) [32]

Логика, логика... ADO, скорее всего, надо создавать в том потоке, в котором используешь: там интерфейсы СОМ. И не так просто передавать интерфейс между потоками ;)
TTimer нужно создавать в execute - там сообщение. Которое придет в тот поток, который зарегистрирован...
И тд. Конечно, не важно, где лежит указатель. Вот только кроме указателя есть куча вещей, которые зависят от потока


 
Джо ©   (2006-11-23 17:46) [33]

> [32] Romkin ©   (23.11.06 17:31)
> Конечно, не важно, где лежит указатель. Вот только
> кроме указателя есть куча вещей, которые зависят от потока

Насчет этого я (и не только я, кажется) уже говорил. Анатолий берет ответственность на себя, утверждая, что с этим он сам разберется :)


 
Leonid Troyanovsky ©   (2006-11-23 18:05) [34]


> Anatoly Podgoretsky ©   (23.11.06 14:28)  

>  SL: TStringList


Если речь идет о чистом TStringList, а не о неких потомках,
то место его создания значения не имеет.
Т.е., он, как раз, является примером thread-safe VCL.
Правда, анализировал исходники еще в D2.

Конечно, в случае с потомками, это легко опровергнуть.

--
Regards, LVT.


 
Anatoly Podgoretsky ©   (2006-11-23 18:14) [35]

> Джо  (23.11.2006 17:05:29)  [29]

Это из почты, которую я ежедневно уничтожаю


 
Anatoly Podgoretsky ©   (2006-11-23 18:16) [36]

> Eraser  (23.11.2006 17:19:31)  [31]

AV это аргумент или нет?


 
Anatoly Podgoretsky ©   (2006-11-23 18:17) [37]

> Джо  (23.11.2006 17:46:33)  [33]

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


 
Anatoly Podgoretsky ©   (2006-11-23 18:23) [38]

> Leonid Troyanovsky  (23.11.2006 18:05:34)  [34]

Чистый стринг лист, чистый HTTPCli, ну и ранее был Absolute Database - все они расчитаны на работу в потоках, сейчас перевожу на АДО
За счет переноса объявлений в Execute проблема была полностью решена. Но сейчас я хочу сильно пересмотреть структуру программы, применить индивидуальные модули данных для каждого потока и желательно его объявить и создавать в Thread.Create
На модуле данных будут лежать вышеуказаные компоненты.


 
guav ©   (2006-11-24 12:40) [39]

> [6] Anatoly Podgoretsky ©   (23.11.06 14:44)


> C третьим все ясно.

Со вторым тоже, тоже из создаваемого потока, ничем от второго не отличается.
Первый из создающего. На время выполнения TThead.Create в последних весриях Delphi новый (создаваемый) поток вообще спит.

Не верите, смотрите генофонд и вызывайте GetCurrentThreadId


 
guav ©   (2006-11-24 12:44) [40]

> На время выполнения TThead.Create в последних весриях Delphi
> новый (создаваемый) поток вообще спит.

... а в не-последних делают так (привожу не псевдокод, а код, и Вы тоже код приводите, его читать легче, а то [2])
constructor TMyThead.Create;
Begin
 inherited Create(True); // создаём остановленным
 SL := TStringList.Create;
 ...
 Resume; // вот тут он пробуждается.
end;


Вроде даже в справке это разжевано...


 
guav ©   (2006-11-24 12:56) [41]

> [30] Anatoly Podgoretsky ©   (23.11.06 17:06)
> Автор утверждает, что первостепенным явлется в контексте
> какого потока создается, а не в контексте какого используется.

"сама переменная" создаётся для всего процесса, даже если она создаётся в стеке потока (имеется ввиду "настоящая" переменная, а не threadvar). Т.е. потоки ей пофиг.
Выделение памяти под указатель сделано потокобезопасным и может осуществлятся из любого потока, в самой RTL есть пример выделения в одном потоке и совобождения в другом.

А вот для кода может быть и не всё равно, ему смена контекста может повредить, если там использован например GetCurrentThreadId для заполнения поля класса. Т.е. контекст вызова конструктора может играть роль.


 
Anatoly Podgoretsky ©   (2006-11-24 13:06) [42]

> guav  (24.11.2006 12:44:40)  [40]

Именно так у меня и сделано, возможно только что сетевые компоненты так нельзя создавать, возможно они что то внутри делают с текущим потоком, тоже для базы.
Автор утверждает, что и создание и сама переменная должны находиться в методе Execute. Более того упирает на слово сама переменная, а не создание или использование.
Именно это меня и смущает. Но я в текущей ситуации уже не могут так, поскольку есть много других методов, ну не передавать же мне туда переменную? А их не одна. Есть модуль данных, есть сетевые компоненты, есть компоненты БД и другие переменные, которые должны быть доступны и в главном потоке. Ну ладно я переместил сетевые компоненты и компоненты БД в модуль данных и если будут проблемы, то буду передавать ссылку на модуль данных.

Мне бы было проще и удобнее, если бы я мог объявить все в секции private, не беспокоясь об их уничтожение и доступности.
Я сейчас не могу проверить технически, поскольку идет полная переделка структуры и поиск оптимального варианта. Через несколько дней я смогу подойти к трассировке.

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

Более того его утверждение нашло физическое подтверждение, перенос переменной сняло вопрос.


 
Slym_RO   (2006-11-24 13:19) [43]

2,3 - в контексте потока, накакать где хранится ссылка на обект
1 - сложнее:
1.1. в контексте потока
constructor TT.Create;
begin
inherited Create(True);
SL := TStringList.Create;
Resume;
end;


1.1. в контексте ОСНОВНОГО потока
constructor TT.Create;
begin
SL := TStringList.Create;
inherited Create(True);
Resume;
end;


 
Slym_RO   (2006-11-24 13:20) [44]

Ганю! 1 всегда в контексте ОСНОВНОГО потока


 
Sly_RO   (2006-11-24 13:33) [45]

Delphi 7
function ThreadProc(Thread: TThread): Integer;
var
 FreeThread: Boolean;
begin
{$IFDEF LINUX}
 if Thread.FSuspended then sem_wait(Thread.FCreateSuspendedSem);
{$ENDIF}
 try
   if not Thread.Terminated then
   try
     Thread.Execute;
   except
     Thread.FFatalException := AcquireExceptionObject;
   end;
 finally
   FreeThread := Thread.FFreeOnTerminate;
   Result := Thread.FReturnValue;
   Thread.DoTerminate;
   Thread.FFinished := True;
   SignalSyncEvent;
   if FreeThread then Thread.Free;
{$IFDEF MSWINDOWS}
   EndThread(Result);
{$ENDIF}
{$IFDEF LINUX}
   // Directly call pthread_exit since EndThread will detach the thread causing
   // the pthread_join in TThread.WaitFor to fail.  Also, make sure the EndThreadProc
   // is called just like EndThread would do. EndThreadProc should not return
   // and call pthread_exit itself.
   if Assigned(EndThreadProc) then
     EndThreadProc(Result);
   pthread_exit(Pointer(Result));
{$ENDIF}
 end;
end;


контекст созданного потока действует только в
Thread.Execute;
Thread.Free; при FreeOnTerminate=true

Thread.OnTerminate; - работает через Synchronize


 
Anatoly Podgoretsky ©   (2006-11-24 13:45) [46]

> guav  (24.11.2006 12:56:41)  [41]

Вот за это и боюсь

> если там использован например GetCurrentThreadId для заполнения поля класса.

Правда автор напирает на место объявления, это он подчеркнул не один раз.
Я не проверял вариант 2, когда объявление в private и создание в методе Execute, сразу перешел к методу 3, когда и объявление в методе Execute и создание объекта в нем же.

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


 
guav ©   (2006-11-24 13:52) [47]

> Более того его утверждение нашло физическое подтверждение,
> перенос переменной сняло вопрос.

Если перенос конструктора снял вопрос, то это можно понять (может они внутри, напимер, TLS используют), но место объявления переменной должно быть безразлично.


> Правда автор напирает на место объявления, это он подчеркнул
> не один раз.

Думаю зря, переменные принадлежат всему процессу.


 
Anatoly Podgoretsky ©   (2006-11-24 13:52) [48]

> Slym_RO  (24.11.2006 13:19:43)  [43]

У меня первый вариант (я учел возможности подобного), только одно замечание конструктор Create всегда выполняется к контексте главного потока.
и Resume у меня выполняется из главного потока, но это не существественно.

Автор утверждает, что обращения к SL будут выполняться в контексте главного потока, а не TT

Мне кажется он ошибается, возможно проблемы в его компоненте, в его внутренней структуре. Но факт остается фактом, перенос определения SL и соответственно Create в Execute решает проблему. Вместо SL можно подставить что угодно, SL только для примера. У меня как я говорил три класса динамических объектов - списки, Интернет компоненты и БД

Я тогда на более ранней стадии не стал разбираться и проверять все три варианта, но сейчас настал момент когда надо поставить точку в этом вопросе.


 
Anatoly Podgoretsky ©   (2006-11-24 13:53) [49]

> Slym_RO  (24.11.2006 13:20:44)  [44]

Пардон, это прочитал после отсылки ответа. Просто не обращай тогда на это замечания внимания.


 
Alexander Panov ©   (2006-11-24 17:38) [50]

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


 
Джо ©   (2006-11-24 18:07) [51]

> [50] Alexander Panov ©   (24.11.06 17:38)
> Не так давно была веточка, в которой некоторые спецы утверждали,
> что поведение объекта не зависит от того, в основном потоке
> он создан, или в дополнительном.

Так дело-то вовсе не в том, в каком потоке он создан. Дело в самой логике работы конкретного объекта.


 
Anatoly Podgoretsky ©   (2006-11-24 18:35) [52]

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


 
Anatoly Podgoretsky ©   (2006-11-24 18:54) [53]

> Anatoly Podgoretsky  (24.11.2006 18:35:52)  [52]

Я нашел первый ответ автора в архиве его конференции

Your HTTP component runs in the main thread since you created in the context
of the main thread (TThread constructor execute in the context of the
calling thread, not in the context of the created thread). Create you HTTP
component instance from the thread"s Execute method and free it at the end
of the Execute method.


 
Anatoly Podgoretsky ©   (2006-11-24 18:56) [54]

> Anatoly Podgoretsky  (24.11.2006 18:35:52)  [52]

Я сейчас приведу значимую переписку

Arno Garrels:
Component events are executed in worker thread context ONLY IF they
are either created in the Execute procedure or if you use methods
ThreadDetach/ThreadAttach instead. The hidden window of a ICS
component must be created in worker thread context.
TThread.Create is executed in the calling thread.


 
Anatoly Podgoretsky ©   (2006-11-24 18:59) [55]

> Anatoly Podgoretsky  (24.11.2006 18:56:54)  [54]

Francois Piette:
There is another issue you seems to ignore. A thread context is not related
at all to the TThread class. It is not because you run a TThread method that
it runs within the conext of the thread created by the TThread class !

A method is executed in the context of a thread only if it is called from
the Execute method (or any method called directly or indirectly by that
execute method). You can have any thread calling any method in a TThread
class instance but then the method is executed within the context of the
CALLING thread, not the context of the thread created by the class.

Speaking ICS components and events, the events are executed in the thread
context which CREATED the component (or the thread attached using
ThreadAttach method). No matter where the event handler is defined. This is
how Windows works.


 
Eraser ©   (2006-11-24 19:11) [56]

> [55] Anatoly Podgoretsky ©   (24.11.06 18:59)


> Speaking ICS components and events, the events are executed
> in the thread
> context which CREATED the component (or the thread attached
> using
> ThreadAttach method). No matter where the event handler
> is defined. This is
> how Windows works.

ну вот это много проясняет.. вот и событийное программирование..

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

надо глянуть исходники ICS..


 
Anatoly Podgoretsky ©   (2006-11-24 19:12) [57]

> Anatoly Podgoretsky  (24.11.2006 18:59:55)  [55]

Ключевой фразой наверно будет эта

Speaking ICS components and events, the events are executed in the thread context which CREATED the component

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

Mythread = thread
  HttpCli: THttpCli;
  AdoDataset: TAdoDataset;
  ThreadDataModule: TDataModule;
  ...
end;

И далее так

procedure MyUnit.Execute;
begin
  HttpCli := THttpCli.Create();
  ThreadDataModule := TAdoDataset.Create();
  AdoDataset := TDataModule.Create();
  ...
end;

На этот раз мои мысли правильные?
Проблем не будет?
Планирую все динамические классы переместить в ThreadDataModule

У меня сейчас почти так, только переменные этого типа локальные в Execute, тут никаких проблем пока обнаружить не удалось. Я каждый вечер запускаю программу под отладчиком и во всех блоках except end установлена точка останова. Попадаю туда только по физическим проблемам, типа таймаут соединения с форумами или счетчиком top.list.ru и также при попытке получить удаленую запись. Больше никаких ошибок.

Надо было давно перечитать то обсуждение. Кое что забыл и переврал :-)


 
Anatoly Podgoretsky ©   (2006-11-24 19:18) [58]

> Eraser  (24.11.2006 19:11:56)  [56]

Очередь сообщений я вырезал из сообщения.


 
Eraser ©   (2006-11-24 19:18) [59]

видимо собака порылась тут )
procedure TIcsWndControl.AllocateHWnd;
begin
   if FHandle <> 0 then
       Exit;              // Already done

   FThreadId := GetCurrentThreadId;
   GWndHandlerPool.Lock;
   try
       if not Assigned(FWndHandler) then
           FWndHandler := GWndHandlerPool.GetWndHandler(MsgHandlersCount,
                                                        FThreadId);

       FWndHandler.AllocateHWnd;
       FHandle := FWndHandler.Handle;
       AllocateMsgHandlers;
   finally
       GWndHandlerPool.UnLock;
   end;
end;


 
Anatoly Podgoretsky ©   (2006-11-24 19:31) [60]

> Eraser  (24.11.2006 19:18:59)  [59]

Вероятно, если вызывать из Create то это будет контекст главного потока.


 
Eraser ©   (2006-11-24 19:34) [61]

> [60] Anatoly Podgoretsky ©   (24.11.06 19:31)

точнее не главного, а вызывающего.


 
Anatoly Podgoretsky ©   (2006-11-24 19:56) [62]

> Eraser  (24.11.2006 19:34:01)  [61]

У меня просто они равны. Вызывается из главного.


 
guav ©   (2006-11-24 21:06) [63]

> [59] Eraser ©   (24.11.06 19:18)
>   FThreadId := GetCurrentThreadId;


гы, угадал (хотя это может быть и не едиснтвенное):

> [41] guav ©   (24.11.06 12:56)
> если там использован например GetCurrentThreadId

И зачем им он нужен ?
И кто отвечает за диспечеризацию сообщений окна ICS в доп потоке ?


> [57] Anatoly Podgoretsky ©   (24.11.06 19:12)
> На этот раз мои мысли правильные?

Думаю, да :-)


 
Leonid Troyanovsky ©   (2006-11-25 12:48) [64]


> Eraser ©   (24.11.06 19:18) [59]

> видимо собака порылась тут )


Скорее всего, что не в подчеркнутом, а в FWndHandler.AllocateHWnd
Хотя, исходников не имею, а лишь догадываюсь, что имеется ввиду.

--
Regards, LVT.



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

Форум: "Основная";
Текущий архив: 2007.01.21;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.65 MB
Время: 0.097 c
15-1167678279
YurikGL
2007-01-01 22:04
2007.01.21
Требования китайских банков


2-1167906518
igor66613
2007-01-04 13:28
2007.01.21
Кнопка из ДЛЛ


3-1162305280
Stanislav
2006-10-31 17:34
2007.01.21
Подключить таблицу из другой базы


2-1167894630
image
2007-01-04 10:10
2007.01.21
Уважаемые мастера, как сделать так, чтобы линия прилипала к компо


4-1157883308
Destroyer
2006-09-10 14:15
2007.01.21
как получить значение переменной среды?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский