VC6.0中关于工作线程使用定时器的问题?

zhuyiwu 2008-11-07 09:29:31
最近在做一个上位机串口通信程序,工作原理如下述:
利用一个工作线程来发送询问命令,等待接收到下位机应答数据后退出。如果两秒下位机未应答,则重发询问命令。重发10次下位机不应答,则认为通信故障,下面为相关代码(编程环境VC6.0):

//启动线程代码(在一个菜单项响应函数中)/////////////////////////////////////////////////////////
m_Thread = AfxBeginThread(SendCommand,this); //this为一个CListView视图类
if(m_Thread->m_hThread!=NULL)
{
m_Thread->m_bAutoDelete=FALSE;
m_Thread->ResumeThread();
}

//线程内使用定时器相关代码//////////////////////////////////////////////////////
UINT CRecordreaderView::SendCommand(LPVOID lParam) SendCommand为static函数
{
CRecordreaderView *m_pView = (CRecordreaderView *)lParam;
/////////////////////
发送查询命令相关代码
////////////////////
::SetTimer(m_pView->m_hWnd,1,2000,NULL);
while(如果收到下位机应答则退出循环) //m_pView为指向当前CListView类的指针
{
if(m_pView->m_bReSend) //判断是否应该重发
{
////////////////////////////////
发送查询命令相关代码(重发)
////////////////////////////////
m_pView->m_bReSend=FALSE;
}
}
::KillTimer(m_pView->m_hWnd,1);
}

////////m_pView(CListView类中的Ontimer函数)//////////
void CRecordreaderView::OnTimer(UINT nIDEvent)
{
CString temp;
switch(nIDEvent)
{
case 1:
m_iReSendcnt++; //重发次数计数器,初始值为0
if(m_iReSendcnt<10)
{
m_bReSend=TRUE; //使线程重发查询命令
}
else
{
m_iReSendcnt=0;
m_bReSend=FALSE;
m_Thread->Delete(); //关闭发送线程
KillTimer(1);
MessageBox("与下位机链接故障!请重新下载!");
}
break;

}
CListView::OnTimer(nIDEvent);
}
问题是如果下位机故障不应答的情况下,该定时器仅响应1次,线程重发1次查询命令,就停止了。线程将永远处于while循环里。在定时器响应函数内设置断点调试,发现定时器响应函数仅仅进入了1次。实在想不通为什么,想死的心都有了。那位大侠知道为什么?或者有保持线程发送查询命令的解决方案不变的情况下实现相同功能的其他方法还请赐教。感激不尽!!!!
另外在该工作线程中通过ListView类指针调用自定义的公共函数,如果函数中有向CFrame类的状态栏写东东的代码,代码也会引起程序崩溃。而在主UI线程中进行同样的操作就没问题,这是为何?
...全文
561 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhuyiwu 2008-11-24
  • 打赏
  • 举报
回复
最后用线程同步的方法解决
//初始化同步事件
hTimer=::CreateEvent(NULL,FALSE,FALSE,NULL);


//线程中的相关代码
CRecordreaderView *m_pView = (CRecordreaderView *)lParam;
/////////////////////
发送查询命令相关代码
////////////////////
while(::WaitForSingleObject(hTimer,2000)==WAIT_TIMEOUT && m_pView-> m_iReSendcnt <10)
{
////////////////////////////////
发送查询命令相关代码(重发)
////////////////////////////////
m_pView-> m_iReSendcnt++;
}
m_pView-> m_iReSendcnt=0;


//接收到下位机应答数据后
::SetEvent(hTimer);//置进程同步变量

非常感谢各位大侠的帮助
liuweibit 2008-11-10
  • 打赏
  • 举报
回复
看了半天都想不出来为什么?不好意思,实在帮不到你,我之前做过一个与硬件通信的程序,在里面我用的是延时来做的Sleep();

7,540

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 VC.NET
社区管理员
  • VC.NET社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧