Форум: "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.48 MB
Время: 0.034 c