2009-12-23 23 views
11

Khi tôi sử dụng SendMessage chức năng với HWND_BROADCAST, ứng dụng bị treo lên. Không có phản ứng từ các ứng dụng trong thời gian dài.SendMessage (HWND_BROADCAST treo

thể bất cứ ai giải thích tại sao?

Trả lời

2

này được vì SendMessage gọi với HWND_BROADCAST đầu tiên liệt kê tất cả các cửa sổ có sẵn và sau đó gọi SendMessage cho mỗi cửa sổ đó. SendMessage sẽ không trở lại cho đến khi cửa sổ đã xử lý xong thông báo. Nếu một cửa sổ mất nhiều thời gian để xử lý tin nhắn, toàn bộ cuộc gọi sẽ bị trì hoãn .

+1

Tệ hơn nữa, nếu một thủ tục gọi là cửa sổ * không bao giờ * trả về sẽ không SendMessage() và ứng dụng sẽ treo vĩnh viễn. Nói chung, bạn không có cách nào để biết cửa sổ của ứng dụng khác sẽ phản hồi như thế nào với một thông điệp tùy ý (thậm chí một cái được tạo bằng RegisterMessage()). Nói một cách đơn giản, bạn không nên gọi SendMessage() để gửi tin nhắn đến cửa sổ trừ khi bạn biết chính xác cửa sổ đó là gì và nó sẽ phản hồi như thế nào. –

0

Có một SendMessageTimeout sẽ giới hạn khoảng thời gian mà ứng dụng của bạn chặn trong khi chờ người nhận chấp nhận.

Cách giải quyết khác là khởi chạy nhiều luồng và yêu cầu chúng phân phối nhiều thư cùng lúc (tức là song song với thư). Sau đó, nếu một trong những người nhận được treo, bạn không giết toàn bộ ứng dụng của bạn.

0

Có ít nhất một quy trình ngoài đó có bơm thông báo nhưng không bơm thông điệp. SendMessage không trả lại cho đến khi tất cả người nhận đã xử lý tin nhắn ... vì vậy nó không trả lại. Bạn có thể thử sử dụng SendMessageTimeout để thay thế.

Ngẫu nhiên, đây là lý do tại sao khởi chạy quy trình và chờ xử lý xử lý có thể gặp nhiều vấn đề. Tôi mô tả điều này trên trang web của tôi here.

15

Điều này sẽ xảy ra khi có quy trình có cửa sổ cấp cao nhất nhưng không gọi GetMessage hoặc PeekMessage trên chuỗi tạo cửa sổ.

Để tương thích ngược với Windows 3.0, SendMessage sẽ không trở lại cho đến khi tất cả các cửa sổ cấp cao nhất trong hệ thống đã phản hồi chương trình phát sóng của bạn. Hành vi này có ý nghĩa trở lại trước khi Windows được đa luồng, bởi vì SendMessage(), ngay cả khi gửi đến các quy trình khác sẽ không bao giờ chặn.

Nhưng bắt đầu với Win32, khi bạn SendMessage đến cửa sổ trong quá trình khác, điều thực sự xảy ra là các chuỗi chuỗi của bạn cho đến khi luồng trong quá trình khác đánh thức và xử lý thư. Nếu luồng đó bận, hoặc không bơm tin nhắn thì bạn sẽ đợi mãi.

Vì lý do đó bạn nên luôn sử dụng SendNotifyMessage hoặc SendMessageTimeout khi bạn sử dụng HWND_BROADCAST hoặc gửi thư đến cửa sổ thuộc sở hữu của các quy trình khác.