2009-05-08 2 views
9

나는 여기에 설명 된 것과 매우 비슷한 문제가 있습니다 (? 5 초) http://www.eggheadcafe.com/software/aspnet/30579866/prevent-vista-from-markin.aspxWindows (구체적으로 Vista)에서 내 응용 프로그램이 멈추었는지 어떻게 확인합니까?

그 스레드가 작업 관리자 프로세스에 WM_NULL를 보내고 프로세스가 시간 제한 내에서이 메시지를 소비 할 것으로 예상 것을 제안합니다. "WM_NULL hanged"에 대해 Google에서 동일한 기술에 대한 많은 참조가 있습니다.

긴 작업에서 작동하는 동안 응용 프로그램의 대기열에 WM_NULL 메시지가 표시되지 않습니다. 주 스레드로 0.5 초 간격으로 전환되고 WM_NULL을 찾는 PeekMessage()를 호출하는 보조 스레드가 있습니다. 그리고 그것은 무엇이든을 찾아 내지 않는다!

Windows (Vista)가 응용 프로그램이 작동하지 않는지 확인하기 위해 사용하는 방법은 무엇입니까?

Windows에서 응용 프로그램이 반응한다고 생각하기 위해 내 응용 프로그램이 소비해야하는 메시지는 무엇입니까?

상세 정보 : 우리는 또한 사용자가 윈도우, 정지 신호의 특정 영역을 포착하면 이해하기 원하기 때문에를 PeekMessage (과 함께

) WM_NULL을 찾고, 우리는 또한, 마우스 이벤트를 PeekMessage()를 호출 그려집니다. 영역이 선택되면 주 스레드의 긴 작업이 주기적으로 검사하는 플래그를 설정하고 정지 신호를 받으면 중지합니다. 비스타의 문제가이 응답하지 않는 등의 응용 프로그램을 선언 할 때, 그것은 유령 창은 창을 대체하는 것입니다 - description of PeekMessage()를 참조하십시오

톱 레벨의 윈도우가 몇 초 이상, 시스템에 대한 메시지에 응답하지 않는 경우 창이 응답하지 않는 것으로 간주하고 동일한 z 순서, 위치, 크기 및 시각적 속성을 갖는 유령 창으로 대체합니다. 이를 통해 사용자는 이동하거나 크기를 조정하거나 응용 프로그램을 닫을 수 있습니다. 그러나 응용 프로그램이 실제로 응답하지 않기 때문에 사용할 수있는 유일한 조치입니다. 응용 프로그램을 디버깅 할 때 시스템에서 고스트 창을 생성하지 않습니다.

이 고스트 윈도우는 더 이상 화면에 윈도우가 없기 때문에 마우스 선택을 허용하지 않습니다!

내가 Michael이 질문

while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 
그의 대답에 제안 된 코드를 추가 한 후 : 그래서 내 목표는 좀 더 INVESTIGATIONS AFTER

... 처음에 표시이 유령 창을 방지하는 것입니다

응용 프로그램이 더 이상 Windows에서 중지되지 않은 것으로 간주됩니다. 그러나 응용 프로그램이 다양한 단추 등을 선택하여 반응하기 때문에이 솔루션을 사용할 수 없습니다 (발생하지 않아야 함). 그래서 어느 메시지가오고 있는지 보려고했습니다. Spy ++와 디버그 프린트를 사용했으며 WM_TIMER와 0x0118 (WM_SYSTIMER)의 두 가지 메시지 만 표시했습니다. 그래서이 코드를 수정했습니다

while (PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE) || 
     PeekMessage(&msg, NULL, 0x0118, 0x0118, PM_REMOVE)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

놀랍게도 응용 프로그램이 다시 중단됩니다 !!

이제 정말로 붙어 있습니다. 들어오는 유일한 메시지를 가로 채고 응용 프로그램에서 처리하도록 할 경우 Windows에서 응용 프로그램이 이벤트를 처리하지 않는다고 생각하는 이유는 무엇입니까 ??

어떤 의미있는 제안

주시면 감사하겠습니다.

+1

UI 스레드에서 무엇을하고 있습니까? 창 관리자를 리버스 엔지니어링하는 대신 블로킹 작업을 백그라운드 스레드로 옮기는 것을 고려 했습니까? –

+1

UI 스레드가 뭔가를 계산 중입니다. 사소한 일이 아니다 이전 코드 멀티 스레드 엄청난 양의하고 많은 거대한 애플리케이션과 마찬가지로 불행하게도, ... :( –

+0

내 대답을 업데이트했습니다. 당신이 고스트되지 않은 상태로 남음됩니다 보장하는 모든 메시지를 배출해야합니다. – Michael

답변

4

윈도우 작업 관리자는 아마도 응용 프로그램이 걸려 있는지 확인 IsHungAppWindow를 사용합니다. MSDN에서 응용 프로그램은 입력을 기다리지 않고 시작 처리 중이 아니거나 5 초 내에 메시지를 처리하지 않은 경우 중단 된 것으로 간주됩니다. 따라서 WM_NULL은 필요하지 않습니다.

당신은 어떤 특정 메시지를 소비 할 필요가 없습니다 - 그냥 정기적으로 메시지를 펌프 및 UI 스레드의 떨어져 긴 작업을 이동합니다. 완전히 메시지 큐를 배출하고 사용자에게 더 반응 나타나게됩니다

while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

: 당신은, 0.5 초마다 호출 같은으로 대체 할를 PeekMessage를 얻을 수 있다면. 마우스 메시지와 같은 개별 메시지를 필터링하지 마십시오. 가능한 경우 매 0.5 초마다이 작업을 수행해야하며 장기간 동안 UI 스레드에서 오랜 작업을 이동하십시오.

+0

내가 언급 한 것처럼, 내 응용 프로그램은 매 0.5 초마다 PeekMessage()를 호출하므로 IsHungAppWindow()는 매달린 것으로보고해서는 안됩니다. –

+0

PM_REMOVE를 지정 했습니까? 아니면 특정 WM_NULL 필터를 지정합니까? MSDN이 여기 오도하는 것 같아요. 실제로 입력 메시지를 큐에서 가져와야합니다. – Michael

+0

예, PM_REMOVE를 지정하고 필터도 제공합니다. 믹스와 최대 모두 WM_NULL입니다. –

0

해결책은 메시지를 발송 한 후 추가로 전화하는 것입니다.


// check for my messages 
while (PeekMessage(&msg, NULL, WM_TIMER, WM_TIMER, PM_REMOVE) || 
     PeekMessage(&msg, NULL, 0x0118, 0x0118, PM_REMOVE)) 
{ 
    TranslateMessage(&msg); 
    DispatchMessage(&msg); 
} 

// only to prevent ghost-window on vista! 
// we dont use the result and let the message in the queue (PM_NOREMOVE) 
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); 

관련 문제