2016-06-22 2 views
1

내 MFC 응용 프로그램에서 나는 네트워크 연결을 수신 대기하고 일부 정보가 도착하자마자 lparam 매개 변수를 통해 해당 정보를 보내도록 SendMessageToDescendants을 호출합니다. 따라서 모든 프레임 윈도우는 메시지를 가져 와서 WM_SYNCHRONOTIFICATION 메시지 (WM_SYNCHRONOTIFICATIONWM_APP+x 메시지)의 메시지 처리기를 통해 처리합니다. 작업자 스레드에서스레드간에 SendMessageToDescendants 사용

코드 : 메인 스레드에서

while (TRUE) 
{ 
    CNotificationMessage notificationmessage; 
    Listen(&notificationmessage); // blocking until some information arrives 

    m_pMainWnd->SendMessageToDescendants(WM_SYNCHRONOTIFICATION, NULL, (LPARAM)(newnotif)); 

    // have all OnSynchroNotification handlers been called here ? 
} 

메시지 핸들러 (간결 간체) :

LRESULT CMyFrame::OnSynchroNotification(WPARAM p1, LPARAM p2) 
{ 
    CNotificationMessage *pNotification = (CNotificationMessage*)p2; 

    // process message (ommited for brevity) 
} 

코드는 잘 작동하지만 난 아니에요 반환시 SendMessageToDescendants에서 모두 OnSynchroNotification이 호출되었는지 확인하십시오.

+4

[어떤 및 SendMessage 다양한 사용하지 마십시오 스레드에서] (http://stackoverflow.com/a/29603742/17034). –

답변

2

가장 간단한 솔루션은 카운터입니다. SendMessage에 전화하기 전에 공유 카운터를 메시지 처리를 원하는 자식 창의 수로 초기화하십시오. 각 메시지 처리기는 작업 완료시 카운터를 감소시키는 역할을 담당하며 이벤트 루프는 더 많은 이벤트를 생성하기 전에 카운터가 0인지 확인할 수 있습니다. 의사 C++에서 :

unsigned int sharedCount; // global/static shared value 

while (TRUE) 
{ 
    CNotificationMessage notificationmessage; 
    Listen(&notificationmessage); // blocking until some information arrives 

    unsigned int current = InterlockedCompareExchange(&sharedCount, activeWindowCount, 0); 
    if (current == 0) 
    { 
     m_pMainWnd->SendMessageToDescendants(WM_SYNCHRONOTIFICATION, NULL, (LPARAM)(newnotif)); 
    } 
    else 
    { 
     // Still processing the last message. 
    } 

    while (InterlockedCompareExchange(&sharedCount, 0, 0) != 0) 
    { 
     Sleep(100); 
    } 
} 

LRESULT CMyFrame::OnSynchroNotification(WPARAM p1, LPARAM p2) 
{ 
    // Processing 
    InterlockedDecrement(&sharedCount); 
} 

경미하게 더 복잡한 솔루션,하지만 당신은 완료 기다리고 CPU를 구울하지 않기 때문에 내가 개인적으로 선호 하나, 다음 윈도우를 처리하는 각 메시지에 대한 이벤트를 생성하는 것입니다 완료 될 때까지 이벤트 루프를 중지하려면 WaitForMultipleObjects (또는 Ex 버전)을 사용하십시오. 또, 의사 C++에서 :

while (TRUE) 
{ 
    CNotificationMessage notificationmessage; 
    Listen(&notificationmessage); // blocking until some information arrives 

    m_pMainWnd->SendMessageToDescendants(WM_SYNCHRONOTIFICATION, NULL, (LPARAM)(newnotif)); 

    DWORD waitResult = WaitForMultipleObjects(activeWindowCount, FrameEvents, TRUE, INFINITE); 
    if (waitResult == WAIT_OBJECT_0) 
    { 
     // Success 
    } 
    else if (waitResult == WAIT_FAILED) 
    { 
     // Failure: Use GetLastError() to figure out why the function call failed. 
    } 

    // Reset the events 
}  

LRESULT CMyFrame::OnSynchroNotification(WPARAM p1, LPARAM p2) 
{ 
    // Processing 
    SetEvent(thisFramesEvent); 
} 

이 예는 무한 제한 시간을 사용하지만, 당신은 항상 합리적인 제한 시간을 설정하고, 시간이 경과 있는지 확인하기 위해 반환 값 WAIT_TIMEOUT를 확인할 수 있습니다.

(필수 면책 조항 : 오류 검사 및 변수 초기화는 간결하고 가독성을 위해서이 두 가지에서 제거 된 오류를 확인하는 방법에 대한 설명서를 참조하십시오.).