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

Вниз

SendMessage & TThread   Найти похожие ветки 

 
axx   (2004-12-16 14:06) [0]

Подскажите коректно ли использование SendMessage в главную форму из TThread. В моем случае я использую параметр Message"a для ведения логов в файле те

procedure TThread.SetError
(SendMessage(Form1.Handle,MY_MESSAGE,1,DWORD(Pchar(".........")));

procedure TForm1.MessageReceiver(var msg: TMessage);
begin
   AddToLog(StrPas(PChar(msg.lParam))); //пишет в файл строку с ошибкой
   msg.Result:=1;
end;


 
Игорь Шевченко ©   (2004-12-16 14:08) [1]


> коректно ли использование SendMessage в главную форму из
> TThread


Корректно.

С уважением,


 
Alex Konshin ©   (2004-12-17 02:23) [2]

Использовать-то корректно, только твоя нить по SendMessage будет ждать до тех пор, пока основная нить (где бежит VCL) не обработает его. Но и PostMessage в твоем варианте использовать нельзя, т.к. ты отсылаешь УКАЗАТЕЛЬ на место в памяти, где в этот момент находится строка, нить же будет проболжать бежать и может использовать ту же область памяти для других нужд.
Т.е. по уму нужно
- либо самому организовывать очередь FIFO и сообщать основной нити лишь о самом факте добавления сообщения в очередь;
- либо самому выделять память, копировать туда содержимое строки и в message передавать указатель на нее, а принимающий должен будет освободить память.
Второй вариант чреват memory leaks, т.к. message может потеряться (не должно, но может), и не будет и сообщения в логе, и ссылка на память потетяется.


 
Ihor Osov'yak ©   (2004-12-17 02:41) [3]

2 [2] Alex Konshin ©   (17.12.04 02:23)

> т.к. message может потеряться (не должно, но может),

Вот-вот... Постоянно такое слышу..  А практически это происходит? Удавалось ли кому нибуть такое наблюдать?  Если происходит, то что такой поворот сюжета провоцирует?
 Зы. Всякие аварийные снятия нитей и процессов не рассматриваем..
Зы2. Ну и слабодокументированные фишки на пример того, что в очереди может находится не более одного сообщения от таймера тоже игнорируем..


 
Alex Konshin ©   (2004-12-17 03:00) [4]

Теоретически ты можешь удалять сообщения. У тебя может быть ошибка при использовании PeekMessage (даже и не в твоем коде). То есть теоретически даже без глюков системы такое возможно и отловить это чрезвычайно трудно. Второй важный момент (как раз-таки очень вероятный для исходной задачи): мы легко можем забить очередь сообщений и приложение просто повиснет. Вывод в лог вполне может генерировать сотни миллионов сообщений в секунду, я не уверен, что при таком повороте событий приложение будет работать корректно. Что например, делать посылающей нити, если PostMessage будет неуспешным?
Вот сейчас я делаю эмулятор процессора SuperH-4, так он легко выполняет 10 миллионов операций в секунду и более. Теперь представь, что будет, если я захочу их трассировать, да еще и с подробностями? Например, при выводе трассы через OutputDebugString  программа DebugView надолго уходила в аут. Когда я делал свой лог я даже и не думал делать это через PostMessage.


 
Alex Konshin ©   (2004-12-17 03:08) [5]

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


 
Ihor Osov'yak ©   (2004-12-17 03:45) [6]

2 Alex Konshin ©

Спасибо. Общая идея понятна..

> У тебя может быть ошибка при использовании PeekMessage (даже и не в твоем коде).

Пару дней назад искал глюк на ровном месте.. Многопоточное приложение, в потоке чего-то там делается, есть цыкл выборки сообщений. Для управения потоком извне в него посылаются сообщения. Из-за лени ради решил для экономии не создавать служебного окна и управляющие сообщения слать прямо потоку. Все нормально. Приложение работает круглосуточно, но раз на пол-дня такое впечатление, что какое-то управляющее сообщение не обрабатывается.. Страдал почти сутки.. Попробуй поймать баг, если он происходит раз в полдня.. И непредсказуемо.   Потом появилась версия. Я там иногда обращался к стороннему COM-обьекту, исходников которого у меня естественно не было.. Предположил, что разработчик этого объекта мог у себя делать маленький циклы ожидания посредством закручивания альтернативного цикла  выборки сообщений. И усе. Там наверное мои сообщения потоку и могли теряться..
С оконными ничего бы плохого не случилось, так как все же DispatchMessage упустить - все же нужно постараться.. Окошко все же служебное писать не стал, сделал все же эхо-ответ на сообщение как квитанцию, благо архитектура решения позволяла..
А через пару дней правдами и неправдами раздобыл исходник того COM - таки да, цикл задержки присутствует... :-(.  

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

> более предпочтительно использовать SendMessageCallback,

Хм. Интересно. Как то раньше не использовал такую технику. Нужно принять во внимание. Еще раз спасибо.


 
Digitman ©   (2004-12-17 09:13) [7]

в случае с асинхронными сообщениями (Post[Thread]Message) не самым худшим решением будет передача параметром таких сообщений интерфейсных ссылок

например :

- передатчик

var intf: IMyIntf;
..

intf := TMyObj.Create as IMyIntf;
try
 intf._AddRef;
 try
   Win32Check(Post[Thread]Message(target, MESSAGE_CODE, Pointer(intf), 0));
 except
   intf._Release;
   raise;
 end;
finally
 intf := nil;
end;

- приемник

var
intf: IMyIntf;
Msg: TMsg;
..
if PeekMessage(Msg, target, MESSAGE_CODE, MESSAGE_CODE, PM_REMOVE) then
intf := IMyIntf(Pointer(Msg.wParam));
try
.. работаем с intf
finally
 intf := nil;
end;

и при завершении работы приемника во избежание мемликов "чистим" очередь от необработанных на этот момент MESSAGE_CODE-сообщений:

while PeekMessage(Msg, target, MESSAGE_CODE, MESSAGE_CODE, PM_REMOVE) do
IMyIntf(Pointer(Msg.wParam))._Release;



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

Форум: "WinAPI";
Текущий архив: 2005.02.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.47 MB
Время: 0.09 c
14-1105405127
Поручик
2005-01-11 03:58
2005.02.06
Как вы думаете


6-1101379631
Неизвестный
2004-11-25 13:47
2005.02.06
Ошибка 10061


1-1106634562
Mamed
2005-01-25 09:29
2005.02.06
RTF Fayli


1-1106487768
Axeman
2005-01-23 16:42
2005.02.06
Internet explorer


1-1106067182
olookin
2005-01-18 19:53
2005.02.06
AV в bordbk50.dll





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский