понедельник, 5 апреля 2010 г.

Сообщения потоку "съедаются" модальным циклом

Это перевод Thread messages are eaten by modal loops. Автор: Реймонд Чен.

Сообщения потоку (создаваемые функцией PostThreadMessage) никак не обрабатываются, будучи переданными в функцию DispatchMessage. Это очевидно, если вы подумаете об этом. Потому что с сообщением потоку не ассоциировано описателя окна. DispatchMessage понятия не имеет, что делать с таким сообщением. У неё нет иного выхода, кроме как проигнорировать сообщение.

Это имеет тяжёлые последствия для потоков, которые входят в модальные циклы, что практически всегда происходит время от времени у всех потоков с окном. Вспомните, что традиционный модальный цикл выглядит примерно так:
while GetMessage(Msg, 0, 0, 0) do
begin
  TranslateMessage(Msg);
  DispatchMessage(Msg);
end;
Если сообщение потоку возвращается функцией GetMessage, то оно просто провалится через вызовы TranslateMessage и DispatchMessage без выполнения работы. Оно потеряно навсегда.

По этой причине, обычно вы должны избегать сообщений потоку, который создаёт окна. Конечно же, если вы собираетесь создать окно, то почему бы вам просто не использовать PostMessage, передавая ваше окно как назначение? Поскольку теперь у вас есть описатель окна, то DispatchMessage знает, кому передать это сообщение. Результат: сообщение не потеряно.

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

Комментариев нет:

Отправить комментарий

Можно использовать некоторые HTML-теги, например:

<b>Жирный</b>
<i>Курсив</i>
<a href="http://www.example.com/">Ссылка</a>

Вам необязательно регистрироваться для комментирования - для этого просто выберите из списка "Анонимный" (для анонимного комментария) или "Имя/URL" (для указания вашего имени и ссылки на сайт). Все прочие варианты потребуют от вас входа в вашу учётку (поддерживается OpenID).

Пожалуйста, по возможности используйте "Имя/URL" вместо "Анонимный". URL можно просто не указывать.

Ваше сообщение может быть помечено как спам спам-фильтром - не волнуйтесь, оно появится после проверки администратором.