проблем с postthreadmessage и peekmessage в delphi 2006

Създадох многодетно приложение. Всички прозорци на приложението (W[n]: TMyWindows) са еднакви и всички имат индивидуален обектен клас, свързан с тях (E: TMyObject). Дъщерните прозорци генерират чрез тези обекти някои съобщения. Създадох в основното приложение две нишки, които обработват тези съобщения в зависимост от съдържанието на съобщенията. Например нека имаме следните асинхронни извиквания:

W[1].E.Service(thread1service)
W[2].E.Service(thread2service)

TMyObject.Service(servicetype) е

case servicetype of
  thread1service: PostThreadMessage(thread1id,...);
  thread2service: PostThreadMessage(thread2id,...);
end;

Сега в метода за изпълнение на всяка нишка имам нещо подобно:

while not terminated do
begin
 ...
 if peekmessage(msg,0,thread1message_1,thread1message_n,pm_remove) then
      process message
 do other things;
end

Всичко върви добре, с изключение на това, че втората нишка не получава никакви съобщения. Имате ли идея защо?


person zoomz    schedule 17.09.2009    source източник


Отговори (3)


Бих проверил, за да се уверя, че диапазонът, който предоставяте на PeekMessage(), е валиден. Опитайте вместо това да поставите нули, за да получавате всички съобщения, като това:

PeekMessage(msg, 0, 0, 0, PM_REMOVE)

Ако това не работи, бих проверил резултата от функцията PostThreadMessage()... Възможно е нишката все още да не е извикала PeekMessage(), това е, което подканва Windows да създаде опашката за съобщения вместо вас.

Както е посочено в тази статия (под „ Забележки"), можете или да проверите резултата от извикването на PostThreadMessage() и Sleep(), ако не успее, или да използвате събитие, за да сигнализирате на основната нишка, че дъщерната нишка е готова да получава съобщения.

HTH,

N@

person Nat    schedule 18.09.2009

Така че трябваше да се откажа, тъй като не намерих никакво рационално обяснение.

Реших да изпращам съобщения, като използвам критична секция със сигнализиране за събитие, за да кажа на работещите нишки, че имат съобщение за обработка. За съжаление, това означава, че основната нишка трябва да провери дали работещата нишка обработва всяко съобщение, преди да изпрати ново.

person zoomz    schedule 20.09.2009
comment
Не е задължително. Дайте на всяка нишка FIFO опашка, защитена от критична секция, и добавете събитие за изчакване. Сигнализира събитието, когато FIFO не е празен. - person mghie; 20.09.2009
comment
Мислех за това, но тогава, ако основната нишка постави много масажи в опашката, работната нишка ще бъде принудена да ги обработи, а работната нишка изпълнява някои критични задачи в своя цикъл. Така че, ако работната нишка обработва някакво съобщение, основната нишка просто изхвърля новите съобщения, вместо да ги изпраща на работната нишка. - person zoomz; 20.09.2009
comment
Наистина жалко, опашка със съобщения в нишка би била идеална. Все още се чудя защо не работи при вас. Проверих изпълнението на това и не изглежда да правите нищо нередно от това, което казвате. :( - person Nat; 22.09.2009

Знам, че това е стар въпрос, но току-що имах подобен проблем в нашия код. Работим с Delphi 2006 на Win 7 64-bit и въпросният код включва DLL, комуникиращ с отделно приложение чрез peekmessage/postthreadmessage.

В крайна сметка успях да проследя проблема до администраторските права, предоставени или на приложението, или на Delphi. Режимът на съвместимост също води до появата на проблема, тъй като изисква предоставяне на администраторски права. Ако са предоставени администраторски права, администраторската нишка може да комуникира с неадминистративната нишка, но неадминистративната нишка не може след това да публикува съобщение обратно в нишката с администраторски привилегии. Обаждането PostThreadMessage на приложението, което не е администратор, отчиташе успех, но съобщението никога не се появяваше в опашката за съобщения на целевото приложение.

Не съм решил проблема, но за щастие успях да стартирам приложението в нормален режим, така че това не беше проблем, освен загубеното време в преследването му.

person Matt Allwood    schedule 04.04.2012