Multithreading 在线程之间使用SendMessageToDescendant

Multithreading 在线程之间使用SendMessageToDescendant,multithreading,winapi,mfc,Multithreading,Winapi,Mfc,在我的MFC应用程序中,我有一个工作线程监听网络连接,当一些信息到达时,我调用sendMessageToDescendats通过lparam参数发送该信息。因此,每个帧窗口将获取消息,并可能通过WM\u SYNCHRONOTIFICATION消息的消息处理程序对其进行处理(WM\u SYNCHRONOTIFICATION是WM\u APP+x消息) 工作线程中的代码:(为简洁起见简化) 主线程中的消息处理程序: LRESULT CMyFrame::OnSynchroNotification(WP

在我的MFC应用程序中,我有一个工作线程监听网络连接,当一些信息到达时,我调用
sendMessageToDescendats
通过lparam参数发送该信息。因此,每个帧窗口将获取消息,并可能通过
WM\u SYNCHRONOTIFICATION
消息的消息处理程序对其进行处理(
WM\u SYNCHRONOTIFICATION
WM\u APP+x
消息)

工作线程中的代码:(为简洁起见简化)

主线程中的消息处理程序:

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

  // process message (ommited for brevity)
}

代码工作正常,但我不确定从
SendMessageToDescendants
返回时是否调用了所有
OnSynchroNotification

最简单的解决方案是使用计数器。在调用
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);
}
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);
}
稍微复杂一点的解决方案,但我个人更喜欢,因为您不必在等待完成时消耗CPU,就是为每个消息处理窗口创建一个事件,然后使用(或Ex版本)停止事件循环,直到完成。同样,在伪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);
}
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\u timeout
,查看时间是否已过

(必需的免责声明:为了简洁易读,错误检查和变量初始化已从这两个版本中删除。有关如何检查错误的信息,请参阅文档。)