Проблема с CEvent

 
0
 
C++
ava
Egoryan | 22.07.2006, 20:03

UINT Thread(LPVOID par)
{
    CTestEventDlg* Dlg=(CTestEventDlg*)par;
    for(int i=0;i<3000;i++)
        Dlg->m_List.AddString("test");
    // .....
    Dlg->event.SetEvent();
    return 0;
}
.................................

void CTestEventDlg::OnButton1() 
{
    CWinThread* thread=AfxBeginThread(Thread,this);
    bool Running=true;
    int result;
    while(Running)
    {
        result=::WaitForSingleObject(this->event.m_hObject,0);  
        if(result==WAIT_OBJECT_0)
            Running=false;
    }
    AfxMessageBox("ended");
}


Разбираюсь с CEvent,написал тестовое приложение. При щелчке на кнопке запускается поток,там выполняются какие-то действия и мне нужно отследить, когда  он завершит свою работу.
В классе диалога создал событие event. В потоковой функции вроде перевожу его в сигнальное состояние но почему-то оно не отслеживается и приложение "виснет"  :stena  
Ответы (8)
ava
Earnest | 23.07.2006, 08:22 #
Неразумно запускать WaitForSingleObject в цикле: поставь один вызов и укжи тайм-аут INFINITE - будет тоже самое, но процессорное время жраться не будет.
Потом проверь отладчиком, доходишь ли ты до SetEvent в потоке.

Добавлено позднее:
Думаю, не доходит, а стоит на первом же AddString. Знаешь, почему? Потому что AddString - это посылка сообщения LM_ADDSTRING окну, которое создано в главном потоке. Который в это время стоит и ждет ивента... Убери нафиг из потока всю работу с окнами - это дурная идея. 
ava
Rapalex | 24.07.2006, 10:43 #
Так как с евентами работать, какая идея, както пытался но так и не понял. Какой у них принцып действия??? 
ava
Earnest | 24.07.2006, 13:49 #
В двух словах: один (поток) ставит, другой ждет. Читай MSDN или, лучше, Рихтера.

Добавлено позднее:
В данном случае события не при чем: Egoryan соорудил классический deadlock: 2 потока ждут друг друга, и никто не работает...  
ava
Rapalex | 26.07.2006, 12:18 #
Понеял, я можно простой примерчик, так на вскидку, к примеру диалог на нажатие кнопки посылает сообщение потоку умереть, и после сего ждёт пока тот не умрёт, после чего выходит из обработчика кнопки.
Как такое реализовать? 
ava
Earnest | 26.07.2006, 18:51 #
Вот, очень схематично:

class CTestEventDlg: public CDialog
{
public:
    CTestEventDlg();

    void OnButton();

    CEvent m_event;
    CWinThread* m_pThread;
};


UINT ThreadProc (LPVOID par)
{
    CTestEventDlg* pDlg = (CTestEventDlg*)par;
     while (true)
     {
        if (WaitForSingleObject (pDlg->m_event, 0) == WAIT_OBJECT_0)
            break;
        // делаем что-нибудь
     }

    return 0;
}
.................................
CTestEventDlg::CTestEventDlg():
    m_event (FALSE, FALSE)
{
   m_pThread = AfxBeginThread (ThreadProc, this);
}

void CTestEventDlg::OnButton() 
{
    m_event.SetEvent();
    
    if (WaitForSingleObject (m_pThread->m_hThread, 15000) != WAIT_OBJECT_0)
    {
        // на всякий случай...
       ::TerminateThread  (m_pThread->m_hThread, -1);
    }

}
 
ava
Rapalex | 08.06.2007, 15:40 #
Цитата (Earnest @  24.7.2006,  13:49 findReferencedText)
 Читай MSDN или, лучше, Рихтера.

Earnest, прошу прощения за задержку, но по ходу у Рихтера книг несколько, так в какой глятуть?
ava
Earnest | 13.06.2007, 09:21 #
Цитата (Rapalex @  8.6.2007,  16:40 findReferencedText)
 у Рихтера книг несколько

В наших магазинах только одну видела\знаю. Но несколько изданий.
Windows для проффесионалов, издание любое, но лучше, конечно, посовременней.
ava
Rapalex | 06.11.2007, 13:58 #
Earnest, Спасибо только что сделал тестовую прогу с твоим кодом, всё работет.
Я так понят эвент это типа булевской переменой, только это обект ядра...

Так у меня новй вопрос возник, а как правильно потоку просигнализировать о том что поток завершон, закончил своё дело?
Зарегистрируйтесь или войдите, чтобы написать.
Фирма дня
Вы также можете добавить свою фирму в каталог IT-фирм, и публиковать статьи, новости, вакансии и другую информацию от имени фирмы.
Подробнее
Участники
advanced
Отправить