您的位置:程序门 -> vc/mfc -> 进程/线程/dll



高分请教啊!!用辅助线程接收消息的问题(只有这么多了,可以追加分啊)


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


高分请教啊!!用辅助线程接收消息的问题(只有这么多了,可以追加分啊)[无满意答案结贴,结贴人:swj0427]
发表于:2007-09-05 18:09:01 楼主
下位机接收上位机发送的信息。只能接受到第一条信息就不动了。

采用的是多线程,创建了一个读的线程。相关代码如下:

1   启动读线程
2   工作者线程
//   工作者线程,负责监视串行口
uint   commproc(lpvoid   pparam)
{
overlapped   os;
dword   dwmask,   dwtrans;
comstat   comstat;
dword   dwerrorflags;

cmodemdlg   *pmodemdlg=(cmodemdlg*)pparam;

memset(&os,   0,   sizeof(overlapped));
os.hevent=createevent(null,   true,   false,   null);

if(os.hevent==null)
{
afxmessagebox( "can 't   create   event   object! ");
return   (uint)-1;
}
while(pmodemdlg-> m_bportopened)
{
dwmask=0;

//   异步操作,等待串口事件,事件结果在dwmask中
if(!waitcommevent(pmodemdlg-> m_hcom,   &dwmask,   &os))  
{
if(getlasterror()==error_io_pending)  
{  
getoverlappedresult(pmodemdlg-> m_hcom,   &os,   &dwtrans,   true);  
}
else   //等待串口事件时出错
{
closehandle(os.hevent);
return   (uint)-1;
}
}

//清除串口可能发生的错误
clearcommerror(pmodemdlg-> m_hcom,&dwerrorflags,&comstat);

if(comstat.cbinque)
{
//   无限等待wm_commnotify消息被处理完
waitforsingleobject(pmodemdlg-> m_hpostmsgevent,   infinite);
resetevent(pmodemdlg-> m_hpostmsgevent);

//   向对话框发送wm_commnotify消息
postmessage(pmodemdlg-> ghwnd,   wm_commnotify,   dwmask,   0);  
continue;
}

}
closehandle(os.hevent);
return   0;
}
3   处理接收到数据消息
lresult   cmodemdlg::oncommrecvnotify(wparam   wparam,   lparam   lparam)
{
updatedata();
//取出接收到的数据
cstring   str=(char*)lparam;
cstring   strtemp;
//获得已有数据
getdlgitemtext(idc_edit_receive,strtemp);
str+= "\r\n ";
str+=strtemp;
//显示所有接收到的数据
setdlgitemtext(idc_edit_receive,str);

//使m_hpostmsgevent成为有信号,即允许发送下一个wm_commnotify消息
setevent(m_hpostmsgevent);  
return   0l;
}
上位机下位机之间采用的是modem   通信
发表于:2007-09-05 18:14:291楼 得分:0
自己调试看代码停在哪里?
发表于:2007-09-05 20:48:352楼 得分:0
晕了,工作者线程是这样的:
dword   winapi   commwatchproc(lpvoid   lpparam)
{
cmodemdlg   *pdlg=(cmodemdlg*)lpparam;
handle   hcomm=pdlg-> hcommdev;
//清空串口,并检查串口是否打开
assert(hcomm!=invalid_handle_value);
//清空串口
purgecomm(hcomm,purge_rxclear ¦purge_txclear);
::setcommmask(hcomm,   ev_rxchar ¦ev_cts ¦ev_dsr);//有哪些串口事件需要监视
//重叠结构
overlapped   ol={0};
ol.hevent=::createevent(null,false,false,null);
        overlapped   readol={0};
readol.hevent=::createevent(null,false,false,null);
dword   dwerrorflags;
char   buf[1024];
dword   dwmask;
dword   dwbytesread;
bool   b;
while(true)
//for(;;)
{  

//等待事件发生
b=::waitcommevent(hcomm,&dwmask,&ol);


if(!b)
{
if(::getlasterror()==error_io_pending)
{
b=::getoverlappedresult(hcomm,&ol,&dwbytesread,true);
}
}
if(b)
{
if(dwmask&ev_rxchar)
{
comstat   comstat;
dword   dwlength;
::clearcommerror(hcomm,&dwerrorflags,&comstat);
dwlength=comstat.cbinque;
        if(dwlength <=0)
{
continue;

}
if(dwlength> 0)
{
//   无限等待wm_commnotify消息被处理完
                        waitforsingleobject(pdlg-> m_hpostmsgevent,   infinite);
                        resetevent(pdlg-> m_hpostmsgevent);

b=::readfile(hcomm,buf,dwlength,&dwbytesread,&readol);

if(!b)
{
if(::getlasterror()==error_io_pending)
{
                                b=::getoverlappedresult(hcomm,&ol,&dwbytesread,true);

}
}
if(b)
{
::postmessage(*pdlg,wm_commnotify,(wparam)hcomm,(long)buf);

       

}
}
}
}

}

return   0;
}
接收到第一组数据就是connect33600之后,就停在
//使m_hpostmsgevent成为有信号,即允许发送下一个wm_commnotify消息
setevent(m_hpostmsgevent);  
这个时候就接不到发送过来的消息了,但是我在串口调试工具里做是通的,可以接收到.

实在是不明白了,各位帮忙看看了
发表于:2007-09-06 10:46:463楼 得分:0
因为你的是多线程,所以按普通的调试步骤有点吃力.
你的界面线程和你的工作线程是并行的(宏观),我认为setevent(m_hpostmsgevent);是绝对不会错的,问题在你的工作线程中,最大的问题在b=::waitcommevent(hcomm,&dwmask,&ol);
请问什么时候你让它返回.
我查了下msdn,说只有   setcommmask   后,waitcommevent   返回.
你让waitcommevent   在while中,而没有setcommmask   ,程序不堵在waitcommevent   才怪.
发表于:2007-09-06 11:50:144楼 得分:0
to:windandsnow(清风和明月游戏)
    我试过了,不行.现在我在考虑是不是需要用定时器来在一端时间内查询一遍呢?waitcommevent是不是只要有串口事件就会被触发呢??


快速检索

最新资讯
热门点击