DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
GMXX* gm = (GMXX*)lpParameter; if (WaitForSingleObject(gm->m_readovp.hEvent, MAX_TIMEOUT) == WAIT_OBJECT_0)
{
ResetEvent(gm->m_readovp.hEvent);
if (gm->m_callback)
{
gm->m_callback->ReadCallback(gm->m_data, _tcslen(gm->m_data));
}
}
else
{
CancelIoEx(gm->m_hDevice, NULL);
}
return 0;
}
在上面的代码中,如果gm已经析构了,那么引用它的成员的时候,程序就会crash,请教各位大虾,遇到这样的问题,如何处理?我尝试过RegisterWaitForSingleObject,UnregisterWaitEx,但不清楚UnregisterWaitEx应该在什么时候去调,msdn上说,必须调用UnregisterWaitEx,并且不能在调用RegisterWaitForSingleObject注册的回调中调用。callbackcrash
{
GMXX* gm = (GMXX*)lpParameter; if (WaitForSingleObject(gm->m_readovp.hEvent, MAX_TIMEOUT) == WAIT_OBJECT_0)
{
ResetEvent(gm->m_readovp.hEvent);
if (gm->m_callback)
{
gm->m_callback->ReadCallback(gm->m_data, _tcslen(gm->m_data));
}
}
else
{
CancelIoEx(gm->m_hDevice, NULL);
}
return 0;
}
在上面的代码中,如果gm已经析构了,那么引用它的成员的时候,程序就会crash,请教各位大虾,遇到这样的问题,如何处理?我尝试过RegisterWaitForSingleObject,UnregisterWaitEx,但不清楚UnregisterWaitEx应该在什么时候去调,msdn上说,必须调用UnregisterWaitEx,并且不能在调用RegisterWaitForSingleObject注册的回调中调用。callbackcrash
把参数new一份副本转过去,这样异步回调函数中就与gm指针无关了
m_data = new XXX;
m_data = gm->m_data;(伪代码,意为拷贝一个副本)
gm->m_callback->ReadCallback(m_data, _tcslen(m_data));
需要用new的方式分配gm->m_data在堆上,然后ReadCallback()里面使用完了以后调一个释放函数来释放gm->m_data
调用
CMyClass x
CMyClass *px = new CMyClass()
*px = x;
HANDLE h = (HANDLE)_beginthreadex(NULL, 0, Proc, px, 0, NULL);
......回调
unsigned CALLBACK Proc(void *e)
{
CMyclass *p = (CMyClass *)e;
......
delete p;
}
类似DWORD DemoThread(LPARAM lParam)
{
THREADINFO *pInfo = (THREADINFO *)lParam;
HANDLE hEvent2[] =
{
pInfo->hExitEvnt, //退出事件。 CreateEvent时用manual-reset方式
pInfo->hDoEvnt //做事事件。CreateEvent时用auto-reset方式
}; BOOL bExitFlag = FALSE;//线程退出标志
while(!bExitFlag)
{
switch(WaitForMultipleObjects(2, hEvent2, FALSE, tmOutTick))
{
case(WAIT_OBJECT_0 + 0)://退出事件
{
//清理退出
bExitFlag = TRUE;
break;
}
case(WAIT_OBJECT_0 + 1)://做事事件
{
//……
break;
}
case(WAIT_TIMEOUT)://超时
{
//处理超时……
break;
}
default://不期望的事件
{
_ASSERT(FALSE);
bExitFlag = -1;
break;
}
}
}
return bExitFlag;
}