Подождите, пока насос сообщений AfxBeginThread / CWinThread будет активен? - PullRequest
1 голос
/ 23 июня 2011

Я вызываю AfxBeginThread и использую CWinThread для раскрутки потока пользовательского интерфейса в моем приложении MFC.

Я заметил, что если мой основной поток попытается PostThreadMessage () в моем новом потоке до CWinThread:: Функция InitInstance () возвращается, затем PostThreadMessage () возвращает ошибку: недопустимый дескриптор потока.

Я предполагаю, что насос сообщений в новом потоке не будет настроен до тех пор, пока не будет возвращен InitInstance.Пример кода, который я видел для AfxBeginThread, и документацию, которую я прочитал, не помогают объяснить это поведение и не показывают шаблон для ожидания инициализации потока.

Что лучшеспособ заблокировать мой главный поток, пока не будет возвращено InitInstance и насос сообщений потока не будет готов к приему сообщений?

Ответы [ 2 ]

4 голосов
/ 23 июня 2011

Вам не нужно ждать сообщения.Вам просто нужно дождаться создания очереди сообщений.Таким образом, насос сообщений будет получать все опубликованные сообщения, когда он наконец запустится.Вот способ, которым, я думаю, вы могли бы сделать это (проверка ошибок опущена):

CEvent myEvent;

CWinThread * myThread = AfxBeginThread( ..., CREATE_SUSPENDED );

QueueUserAPC( MyCallback, *myThread, reintepret_cast<ULONG_PTR>( &myEvent ) );

myThread->Resume();

WaitForSingleObject( myEvent, INFINITE );

В Windows, как только поток запускается, он запускает любые пользовательские APC в очереди перед вызовом своей точки входа.Таким образом, это позволяет вам проникнуть в некоторый код в новом потоке, прежде чем MFC Framework вступит во владение.Ваш обратный вызов APC будет выглядеть примерно так:

VOID CALLBACK MyCallback( ULONG_PTR param )
{
    // Call peek message to force the creation of the thread's message queue.
    MSG dummy;

    PeekMessage( &dummy, NULL, 0, 0, PM_NOREMOVE );

    CEvent * pEvent = reinterpret_cast<CEvent *>( param );

    pEvent->SetEvent();
}
1 голос
/ 23 июня 2011

Ответ Питера хорош тем, что он признал, что «вам просто нужно дождаться создания очереди сообщений». Это открытие привело к тому, что в связанных ответах появилась следующая ссылка: WaitForSingleObject возвращает ожидание, не выполненное из-за неверного дескриптора , который демонстрирует более простой способ сделать то, что предлагает Питер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...