MFC界面假死解决方案

遇到繁忙的任务,mfc界面假死,不再响应,解决办法有两种

1.另开线程处理繁忙任务

2.在循环中强制分发消息 并响应。

第2种解决办法应对的场景:繁忙任务可以拆分切片,在循环体里多次调用。如果繁忙任务不可拆分,只能使用第一种办法,另开线程处理(不可拆分的情况:例如,调用外部封装的库函数,延时返回结果之前无法干预)。

第2种解决办法又分两种方式(看起来不同,但本质一样,代码也大同小异)

2.1 手动写出完整消息机制 窥视消息->过滤预翻译消息->翻译消息/分发消息

   

    int i=0;
    MSG _msg;
    while (1)//模拟任务循环
    {
        i++; //繁忙的任务
        if (PeekMessage(&_msg, NULL, 0, 0, PM_REMOVE))
        {
            if (!PreTranslateMessage(&_msg))
            {
                TranslateMessage(&_msg);
                DispatchMessage(&_msg);
            }
        }    
    }

2.2 一行封装好的代码 实现 消息循环

    int i=0;
    MSG _msg;
    while (1)
    {
        i++;
        AfxPumpMessage(); //包含完整的 窥视/过滤/翻译/分发消息 环节
    }

针对解决方案2.1中 PeekMessage参数PM_REMOVE的说明:

peekmessage为什么不可以用 PM_NOREMOVE? 必须移除消息? 因为繁忙任务造成消息阻塞无法响应,只能走自己实现的流程:强制分发响应,这个流程中也要模拟底层机制,及时拿到消息并移除,防止peekmessage拿到重复消息死循环(界面假死就解决不了了)。这涉及底层的消息机制:

while (GetMessage(&_msg, NULL, 0, 0))//注意GetMessage 默认会从队列中移除消息
{	
    if (!PreTranslateMessage(&_msg))
    {
	TranslateMessage(&_msg);
	DispatchMessage(&_msg);
    }	
}

2.1需要自己理解消息机制的细节,正确使用参数PM_REMOVE。

2.2最简洁,AfxPumpMessage一行代码搞定,封装屏蔽了技术细节。

  • 6
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值