2015-08-18 3 views
1

Я читал разные темы, касающиеся использования WaitForSingleObject(), но я до сих пор не понимаю, почему я не могу заставить его работать. У меня есть индикатор выполнения, который обновляется с использованием AfxBeginThread, и я хотел бы подождать, чтобы закончить работу, прежде чем делать другой процесс. Мой код основан на следующем примере: http://www.codeproject.com/Articles/2459/Using-AfxBeginThread-with-class-member-controllingКак использовать WaitForSingleObject()

startupEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); 
THREADSTRUCT *_param = new THREADSTRUCT; 
_param->_this = this; 
CWinThread* thread = AfxBeginThread (StartThread, _param); 
WaitForSingleObject(startupEvent , INFINITE); 
AfxMessageBox(_T("This message should pop up after the thread terminates.")); 

Я определил startupEvent переменную в файле заголовка, как это:

protected: 
    HANDLE startupEvent; 

Вот метод резьбы.

UINT CView::StartThread (LPVOID param) 
{ 
    THREADSTRUCT* ts = (THREADSTRUCT*)param; 
    ::SetEvent(ts->_this->startupEvent); 
    //Some heavy calculation from here + ProgressBar update 
    return 1; 
} 

В приведенном выше примере, я хотел бы, чтобы MessageBox появиться после того, как нить прекратить proccess, но в настоящее время он появляется раньше.

+3

Как насчет, может быть, вызова ':: SetEvent (ts -> _ this-> startupEvent);' когда задание закончилось, а не раньше? –

+0

Я попытался вызвать его, когда работа закончена, но она выглядит застрявшей в бесконечном цикле (индикатор выполнения не обновляется, и я больше не могу нажимать на графический интерфейс) – oro777

+0

@ oro777 Это потому, что ваш основной поток (который обрабатывает графический интерфейс пользователя)) ожидает, пока поток будет сигнализировать о событии. – molbdnilo

ответ

3

Короткий ответ на ваш вопрос: вам нужно позвонить ::SetEvent(ts->_this->startupEvent);, после тяжелых вычислений, в противном случае WaitForSingleObject вернется до начала тяжелый расчет.

Сторона примечания: вы можете использовать WaitForSingleObject непосредственно на ручке потока, поэтому вам не нужно дополнительное событие. Как: WaitForSingleObject(thread->m_hThread, INFINITE);

Bad практики

Ваше решение содержит 2 дурные практики:

  1. Это плохая идея, чтобы заблокировать ваш главный-нить, так как он запускает основной цикл обработки сообщений, которые в очередь отвечает за перерисовку элементов графического интерфейса (например, обновление панели результатов в вашем случае). Предоставление основному потоку ожиданий завершения рабочего потока поражает причину разгрузки тяжелого расчета на вторичный поток.

  2. Не касайтесь графического интерфейса рабочего стола. Рабочий поток может использовать SendMessage или PostMessage для отправки сообщений о статусе в основной поток, который, в свою очередь, обновит пользовательский интерфейс. Я нашел старый, но все еще релевантный article по этому вопросу.

+1

Пожалуйста, напишите тривиальные наблюдения как комментарии. –

+1

@ Cheersandhth.-Alf Если он отвечает на вопрос, он должен быть отправлен как ответ, независимо от того, насколько тривиальным является –

+0

. Как я могу использовать дескриптор потока на WaitForSingleObject? Правилен ли следующий код? WaitForSingleObject (thread-> m_hThread, INFINITE); Я не понимаю, почему он блокирует мой основной поток, вы имеете в виду AfxMessageBox? Это был просто пример, на самом деле я делаю обновление объектов GUI. – oro777

Смежные вопросы