CMainFrame::OnCreate 中开线程,线程函数中需要访问CMainFrame类的变量,引起的致命问题(花费时间:20090727-20090729)
问题简述
由于在VS6.0单文档程序中,使用了MS的MSComm.OCX控件,因此程序无法DEBUG运行,鉴于对串口控件及串口编程的不熟悉性,对程序中的多个应用进行了质疑和测试,因此只能Release测试问题所在,后经提取质疑段代码进行DEBUG测试,发现问题指向线程函数访问CMainFrame的成员变量时,堆栈指向
((CMainFrame*)AfxGetMainWnd())->bThreadExit
//这个bool类型量用来控制线程的退出
或
((CMainFrame*)AfxGetMainWnd())->m_ghEvent
//这个HANDLE用来控制线程的信号状态
又经VCKBASE的请教,找出了解决问题的方法
回复人: yangtze (大学士) 2009-7-28 16:48:05 (得分:28)
CMainFrame::OnCreate: 窗口还弱智状态呢
回复人: yangtze (大学士) 2009-7-28 16:51:09
看看 CDocument::OnNewDocument
//经测试发现错误更加直接和致命
回复人: yangtze (大学士) 2009-7-28 16:55:58
这样吧:在FrameWnd里,弄个 1s定时器,在OnTime里面,1)Kill定时,启动线程
回复人: yangtze (大学士) 2009-7-28 16:59:56
呵呵:听我的,那样做,也就是“一开始”!窗口初始化完成,立即处理1s的定时消息,你根本感觉不到
回复人: bl (举人) 2009-7-28 17:00:12
不用。。在 CMainFrame::OnCreate里面 PostMessage一个自定义消息。在消息里面做就行了。
回复人: PerfectToday (书童) 2009-7-28 17:05:06
总问:题述问题也许真的是初始化导致的吗????
回复人: yangtze (大学士) 2009-7-28 17:05:25
yes
回复人: yangtze (大学士) 2009-7-28 17:06:31
是!因为,你的thread里面,要获取 MainFrame
问题重现内容
第一步:创建单文档VS6.0程序,创建菜单函数,OnMenuStartService
SetEvent( m_ghEventOfRunDays );
hThreadIDOfRunDays = NULL;
bThreadExitOfRunDays = false;
nThreadIDOfRunDays = 0;
//计算运行天数线程
hThreadIDOfRunDays = (HANDLE)_beginthreadex(NULL,
0,
RUNDAYS,
NULL,
0,
&nThreadIDOfRunDays);
//单次计算信号强度线程
nThreadIDCSQ1 = 0;
HANDLE hThread = (HANDLE)_beginthreadex(NULL,
0,
CSQ1,
NULL,
0,
&nThreadIDCSQ1);
第二步:线程函数实现代码如下
CTime tm;
CString strRunTime;
CString strTemp;
unsigned __stdcall RUNDAYS(void * pArguments = NULL)
{
while(1)
{
if( ((CMainFrame*)AfxGetMainWnd())->bThreadExitOfRunDays )
{
_endthreadex(0);
CloseHandle(((CMainFrame*)AfxGetMainWnd())->hThreadIDOfRunDays);
((CMainFrame*)AfxGetMainWnd())->hThreadIDOfRunDays = NULL;
return 0;
}
DWORD dwWait = WaitForSingleObject(((CMainFrame*)AfxGetMainWnd())->m_ghEventOfRunDays,
10000);
switch(dwWait)
{
case WAIT_OBJECT_0:
{
}
break;
case WAIT_FAILED:
break;
case WAIT_TIMEOUT:
SetEvent(((CMainFrame*)AfxGetMainWnd())->m_ghEventOfRunDays);
break;
default:
break;
}
};
return 0;
}
unsigned __stdcall CSQ1(void * pArguments = NULL)
{
_endthreadex(0);
return 0;
}
第三步:在CMainFrame::OnCreate中执行
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
OnMenuStartService(); //
return 0;
}
总结
上述问题发生在为了让软件自动运行序列功能时出现,所以今后在做类似工作时,应该考虑框架类是否初始化完整。
Release出错提示