我有一个事件处理线程类,它允许我从其他线程引发事件而不会中断它们的操作。当调用析构函数时,我向线程发送退出消息,但它的消息循环似乎没有收到此消息。
#include <iostream>
using namespace std;
#include <windows.h>
#define WIN32_LEAN_AND_MEAN
#define ET_EVENTPUSH 7854
#define ET_QUITLOOP 6581
#define EVENT_HANDLER void
typedef void (*EVENT)(LPVOID);
//# event handler thread
class event_thread
{
private:
//vars
HANDLE m_thread; //event loop thread
DWORD m_id; //thread id
//thread procedure
static DWORD WINAPI listener_loop(LPVOID);
public:
//constructor
event_thread();
~event_thread();
//functions
void push_event(EVENT, LPVOID);
};
//# event handler thread
event_thread::event_thread()
{
//create thread
m_thread = CreateThread(NULL, 0, listener_loop, NULL, 0, &m_id);
}
event_thread::~event_thread()
{
DWORD dw;
//stop thread
if (m_thread)
{
dw = GetLastError();
PostThreadMessage(m_id, ET_QUITLOOP, 0, 0);
dw = GetLastError();
WaitForSingleObject(m_thread, INFINITE);
CloseHandle(m_thread);
}
}
void event_thread::push_event(EVENT e, LPVOID p)
{
PostThreadMessage(m_id, ET_EVENTPUSH, (UINT)e, (UINT)p);
}
DWORD WINAPI event_thread::listener_loop(LPVOID param)
{
MSG msg;
#define event_type msg.message
#define event_call ((EVENT)(msg.wParam))
#define event_param (LPVOID)(msg.lParam)
//while thread is alive
while (GetMessage(&msg, NULL, 0, 0))
{
switch (event_type)
{
case ET_EVENTPUSH:
event_call(event_param);
break;
case ET_QUITLOOP:
return 0;
}
}
return 0;
}
EVENT_HANDLER asda(LPVOID as)
{
cout << (int)as << endl;
}
int main()
{
event_thread thr;
int i = 1;
while (!GetAsyncKeyState(VK_NUMPAD1))
{
thr.push_event(asda, (LPVOID)(i++));
Sleep(20);
}
return 0;
}
GetMessage
当我发送退出消息时不返回。并GetLastError()
在PostThreadMessage
通话后使用 1444 ERROR_INVALID_THREAD_ID
。
我不想使用PeekMessage
,因为它使用 100% CPU,也不Sleep
是因为这显然是不好的做法。
谢谢