Доброго времени суток! Есть класс: | Код | ///////////////////////////////////////////////////////////////////////////////////////////////// // CWiseThread class CWiseThread {
public: HANDLE m_hThread; //хэндл потока DWORD m_dwThreadId; //ID потока
public: CWiseThread(); virtual ~CWiseThread();
// Создаёт поток // param lpThreadAttributes атрибуты доступа // param uiStackSize размер стэка // param dwCreationFlags флаг // return TRUE в случае успеха BOOL CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL, unsigned int uiStackSize = 0, DWORD dwCreationFlags = CREATE_SUSPENDED);
// Возобновляет поток return TRUE в случае успеха BOOL Start() { return (::ResumeThread(m_hThread) != -1); }
// Выполняет завершение потока // param dwMilliseconds - время в миллисекундах ожидания завершения потока // return TRUE, если поток завершился коректно BOOL Cancel(DWORD dwMilliseconds);
// Приостанавливает поток return TRUE в случае успеха BOOL Pause() { return (::SuspendThread(m_hThread) != -1); }
// Отправляет сообщение потоку // Msg Сообщение // param wParam параметр 1 // param lParam параметр 2 // return TRUE в случае успеха BOOL PostThreadMessage(UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0) { return ::PostThreadMessage(m_dwThreadId, Msg, wParam, lParam); }
// Устанавливает приоритет // param nPiority Приоритет // return TRUE в случае успеха BOOL SetThreadPriority(int nPiority) { return ::SetThreadPriority(m_hThread, nPiority); }
// Возвращает хендл потока operator HANDLE() const { return m_hThread; }
BOOL IsRun() { return m_fRunThread; }
private: static unsigned WINAPI ThreadProc(LPVOID param); // Фукнция потока
protected: virtual BOOL Process(); // Рабочая функция return FALSE, если функция завершает работу потока virtual BOOL OnDone();
private: volatile BOOL m_fRunThread; // Флаг, состояния потока если FALSE, то обработчики сообщений потока должны немедленно завершать свою работу };
|
| Код | ///////////////////////////////////////////////////////////////////////////////////////////////// // CWiseThread CWiseThread::CWiseThread(void): m_hThread(NULL) { m_dwThreadId = 0; }
CWiseThread::~CWiseThread(void) { Cancel(0); ::CloseHandle(m_hThread); }
//=========================================================================== CreateThread BOOL CWiseThread::CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, unsigned int uiStackSize, DWORD dwCreationFlags) { //m_hThread = (HANDLE)_beginthreadex(lpThreadAttributes, uiStackSize, ThreadProc, (LPVOID)this, dwCreationFlags, (unsigned*)&m_dwThreadId); m_hThread = (HANDLE)::CreateThread(lpThreadAttributes, uiStackSize, (LPTHREAD_START_ROUTINE)ThreadProc, (LPVOID)this, dwCreationFlags, &m_dwThreadId);
if(m_hThread) m_fRunThread = TRUE;
return (m_hThread != NULL); }
//=========================================================================== Quit BOOL CWiseThread::Cancel(DWORD dwMilliseconds) { m_fRunThread = FALSE; SetThreadPriority(THREAD_PRIORITY_HIGHEST); DWORD res = PostThreadMessage(WM_QUIT);
return (WaitForSingleObject(*this, dwMilliseconds) == WAIT_OBJECT_0); }
//=========================================================================== ThreadProc unsigned WINAPI CWiseThread::ThreadProc(LPVOID param) { CWiseThread* pThread = (CWiseThread*)param;
MSG msg; BOOL fDone = FALSE;
while(!fDone) { //GetMessage(&msg, NULL, 0, 0) if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { if (msg.message == WM_QUIT) fDone = TRUE; } else { if (!pThread->Process()) break; } }
pThread->m_fRunThread = FALSE; pThread->OnDone();
return 0; }
//=========================================================================== Process BOOL CWiseThread::Process() { return TRUE; }
//=========================================================================== OnDone BOOL CWiseThread::OnDone() { return TRUE; }
|
Вопрос такой при попытке вызова Cancel() выполняется | Код | BOOL PostThreadMessage(UINT Msg, WPARAM wParam = 0, LPARAM lParam = 0) { return ::PostThreadMessage(m_dwThreadId, Msg, wParam, lParam); }
|
::PostThreadMessage(m_dwThreadId, Msg, wParam, lParam) возвращает 0 т.е. выполняется с ошибкой -> сообщение в PeekMessage() не ловится -> функция потока не завершается, проблема скорее всего в том, что нет очереди сообщений потока, как её установить? И как вообще правильно передавать сообщения потоку, например об принудительном выходе из функции потока или передачи в него каких либо данных?
|