5734|13

74

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

由模态对话框引起的程序错误 [复制链接]


首先我定义了一个串口类创建了一个接收线程,当串口收到数据的时候发送消息到主框架(mainframe)进行数据处理,此时如果弹出一个模态对话框(例如messagebox),就有可能导致程序错误,不是每次弹出都有错误,但是多弹出几次就一定会出现一个“致命的程序错误”,如果弹出的是非模态的对话框就没有问题.
出现错误提示的同时,也会弹出下面程序里面由于不能从串口读取数据而弹出的“Error in read from serial port”对话框。


while (pThis->m_hComPort != INVALID_HANDLE_VALUE)
    {
               
        //等待串口的事件发生
        WaitCommEvent (pThis->m_hComPort, &dwCommModemStatus, 0);
               
        if (dwCommModemStatus & EV_RXCHAR)
        {                       
            ClearCommError(pThis->m_hComPort,&dwErrorFlags,&ComStat);

            //cbInQue返回在串行驱动程序输入队列中的字符数
            dwLength=ComStat.cbInQue;
            if(dwLength>0)
            {
                //从串口读取数据
                char* buf = new char[dwLength];
                fReadState=ReadFile(pThis->m_hComPort,buf,dwLength,&dwLength,NULL);
                if(!fReadState)
                {
                    //不能从串口读取数据
                    MessageBox(NULL,TEXT("Error in read from serial port"),TEXT("Read Error"),MB_OK);
                    return;
                }
                else
                {
                    
                    //把数据赋值给全局变量
                    memset(pThis->m_RecvString, 0, 100);
                    memcpy(pThis->m_RecvString, buf, dwLength);
                    ::PostMessage(pThis->m_ParentWnd, WM_RECV_DATA, 0, dwLength);//发送消息至主框架
                }
                               
                delete[] buf;
            }     
        }
        GetCommModemStatus (pThis->m_hComPort, &dwCommModemStatus);
               
    }

是由于模态对话框引起的线程阻塞?内存泄露? 还是什么原因.....

但是如果把::PostMessage(pThis->m_ParentWnd, WM_RECV_DATA, 0, dwLength);修改成为
SendMessage(pThis->m_ParentWnd, WM_RECV_DATA, 0, dwLength);就不存在这样的问题了...为什么呢?

相当于现在我有两个线程,一个主线程,一个是串口的接受线程,而从接收线程用PostMessage发消息会出错(在有模态对话框的情况下),模态对话框会导致这两个线程怎样?
       

最新回复

VIEW类开始显示数据之后  详情 回复 发表于 2008-3-19 08:12
点赞 关注

回复
举报

70

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
没有人知道么?
 
 

回复

62

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
你对全局变量pThis-> m_RecvString
的操作没有加任何同步机制。

在主线程中可能正在操作全局变量,由于模态对话框出现,使操作暂停了。
但是此时读线程却还能操作全局变量,引起不可预测的问题。

建议用event等来处理。

强力建议 多看一下多线程的知识。
 
 
 

回复

71

帖子

0

TA的资源

一粒金砂(初级)

4
 
PostMessage是直接返回的。不用等待消息处理完。

SendMessage必须等待消息处理完,所以躲过了同步问题
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

5
 
不建议用SendMessage
 
 
 

回复

72

帖子

0

TA的资源

一粒金砂(初级)

6
 
lenux说的很对,但是我的问题是 模态对话框会使主线程操作暂停么?还是由于postmessage放消息到消息对列中,而模式对话框关闭的时候也传递了消息到主框架,这样就有可能在处理消息的时候造成对内存的既读又写的操作,造成错误?
 
 
 

回复

82

帖子

0

TA的资源

一粒金砂(初级)

7
 
为什么不用sendmessage?
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

8
 
SendMessage等待消息处理
 
 
 

回复

56

帖子

0

TA的资源

一粒金砂(初级)

9
 
如果你的模式对话框是在主线程里生成的,肯定是要使主线程暂停,等待对话框的返回。

“还是由于postmessage放消息到消息对列中,而模式对话框关闭的时候也传递了消息到主框架,这样就有可能在处理消息的时候造成对内存的既读又写的操作,造成错误?”

是什么意思?

你的问题是多线程处理中没有对全局资源进行同步保护。和你的消息怎么处理没有关系。
 
 
 

回复

87

帖子

0

TA的资源

一粒金砂(初级)

10
 
可是我弹出模式对话框的时候,主线程并没有暂停啊 依然在处理读线程发过来的数据....

 
 
 

回复

88

帖子

0

TA的资源

一粒金砂(初级)

11
 
哦,那倒要看看代码了。
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

12
 
读线程:
串口接收到数据
SendMessage(父窗口句柄(主框架), WM_REC_DATA, 0, 0);

主线程:
LRESULT CMainFrame::OnRecvData(WPARAM wParam, LPARAM lParam)
{
   ...数据处理得到结果发送到活动VIEW类窗口显示
   SendMessage(GetActiveView()->GetSafeHwnd(), WM_DATA, 0, 0);  //发送消息至活动窗口
}
//VIEW类来显示数据
LRESULT CVIEW::OnProcessData(WPARAM wParam, LPARAM lParam)
{
   显示数据:
   SetDlgItemText(ID,数据);
}
主线程弹出模态对话框:
CMainFrame::OnDoModal()
{
   MessageBox("主线程测试");
}


当弹出对话框的时候,如果主线程不处理其他消息,VIEW类就不应该再有数据更新显示了吧,可以依然又数据显示

 
 
 

回复

73

帖子

0

TA的资源

一粒金砂(初级)

13
 
什么时候调用的OnDoModal()
 
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

14
 
VIEW类开始显示数据之后
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表