MsgWaitForMultipleObjects 后遗症 与解决办法

关于MsgWaitForMultipleObjects 的使用[主线程中WaitForSingleObject/WaitForMultipleObjects的替代方案] 在这两天的工作中,遇到了一个问题,在主进程中通过 CreateProcess 打开另外一个进程,然后使用 WaitForSingleObject 来进行调用进程的阻塞,等待被调用进程的返回,但是在被调用进程运行期间,如果对调用进程操作,将会出现一些奇怪的现象,就像是所有在开启子进程时的各种事件全部被快速地执行了。如下图 Demo 所示: 这是由于 WaitForSingleObject 阻塞... 阅读详情

在 调用SendMessage 产生死锁的问题分析 之后,我在界面程序中不再使用 WaitForSingleObject 了,而改用如下的函数

DWORD WaitObjectAndMsg(HANDLE hEventThread, DWORD dwMilliseconds)
{
BOOL bWait = TRUE;
DWORD dwEvt = 0;

while(bWait) 
{
DWORD dwEvt = ::MsgWaitForMultipleObjects(1 , &hEventThread, FALSE, dwMilliseconds, QS_ALLINPUT);

switch (dwEvt) 
{
case WAIT_OBJECT_0: 
{
return WAIT_OBJECT_0;
}
break;

case WAIT_OBJECT_0 + 1: 
{
MSG msg;
while ( ::PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) 
{
if( WM_CLOSE == msg.message || WM_QUIT == msg.message ) 
{
return WAIT_FAILED;
break;
} 
else 
{
PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);

::TranslateMessage(&msg); 
::DispatchMessage(&msg); 
}
} 
break;
} 

default: 
{
return dwEvt;
break;
} 

} 
}

return dwEvt;
}



这个函数看起来不错,在等待一个 Object 的同时,还可以边等待,边处理消息
今天才发现,这样处理有缺陷

如果在等待一个Object 时,哪怕只有 0.00001 秒,这里如果一个不小心处理了消息

那么 很自然会走到这个语句 ::DispatchMessage(&msg);

经过调试发现, ::DispatchMessage(&msg); 是阻塞的,

如果在处理消息的函数里,调用了一个

CDialog dlg;
dlg.DoModal(); 这里也是阻塞的, 如果这个窗口一直不关闭,

即使这时候 Object 已经响应了,但这个函数仍然不返回,,,,,,,因为它在双重的消息处理中。。。。。。。

下面是可参考解决办法

One danger of theMsgWaitForMultipleObjects functionis calling it when there are already messages waiting to be processed, because MsgWaitForMultipleObjectsreturns only when there is a new event in the queue.

In other words, consider the following scenario:

  • PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) returns TRUE indicating that there is a message.
  • Instead of processing the message, you ignore it and call MsgWaitForMultipleObjects.

This wait will not return immediately, even though there is a message in the queue. That's because the call toPeekMessage told you that a message was ready, and you willfully ignored it. TheMsgWaitForMultipleObjects message tells you only when there are new messages; any message that you already knew about doesn't count.

A common variation on this is the following:

  • MsgWaitForMultipleObjects returns that there is a message.
  • You call PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) and process that message.
  • You call MsgWaitForMultipleObjects to wait for more messages.

If it so happens that there were two messages in your queue, theMsgWaitForMultipleObjects does not return immediately, because there are no new messages; there is an old message you willfully ignored, however.

When MsgWaitForMultipleObjects tells you that there is a message in your message queue, you have to processallof the messages untilPeekMessage returnsFALSE, indicating that there are no more messages.

Note, however, that this sequence is not a problem:

  • PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) returns FALSE indicating that there is no message.
  • A message is posted into your queue.
  • You call MsgWaitForMultipleObjects and include the QS_ALLPOSTMESSAGE flag.

This wait does return immediately, because the incoming posted message sets the "There is a new message in the queue that nobody knows about" flag, whichQS_ALLPOSTMESSAGE matches and therefore causesMsgWaitForMultipleObjects to return immediately.

TheMsgWaitForMultipleObjectsEx functionlets you pass theMWMO_INPUTAVAILABLE flag to indicate that it should check for previously-ignored input.

Armed with this knowledge, explain why the observed behavior with the following code is "Sometimes my program gets stuck and reports one fewer record than it should. I have to jiggle the mouse to get the value to update. After a while longer, it falls two behind, then three..."

// Assume that there is a worker thread that processes records and
// posts a WM_NEWRECORD message for each new record.

BOOL WaitForNRecords(HANDLE h, UINT cRecordsExpected)
{
  MSG msg;
  UINT cRecords = 0;
  while (true) {
    switch (MsgWaitForMultipleObjects(1, &h,
                         FALSE, INFINITE, QS_ALLINPUT)) {
    case WAIT_OBJECT_0:
      DoSomethingWith(h); // event has been signalled
      break;
    case WAIT_OBJECT_1:
      // we have a message - peek and dispatch it
      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
      if (SendMessage(hwndNotify, WM_GETRECORDCOUNT,
                      0, 0) >= cRecordsExpected) {
        return TRUE; // we got enough records
      }
      break;
    default:
      return FALSE; // unexpected failure
    }
  }
}


 

MsgWaitForMultipleObjects函数的一种用法 工程是VS2010,具体描述了如何在主线程中用MsgWaitForMultipleObjects等待子线程结束的同时,处理子线程发送的界面消息。 立即下载

相关推荐

SAP PP后台配置实战:从BOM到工艺路线的全流程解析

本文详细解析了SAP PP模块后台配置的全流程,从BOM到工艺路线的关键步骤与实战技巧。通过分享生产计划、工作中心能力计划等核心配置经验,帮助企业优化生产管理流程,提升SAP系统实施效率。特别针对BOM配置、工艺路线设置等常见问题提供解决方案。

weixin_29300931的博客 1010

MsgWaitForMultipleObjects

用户模式:WaitForMultipleObject 内核模式:MsgWaitForMultipleObjects 用户模式的线程同步机制效率高,如果需要考虑线程同步问题,应该首先考虑用户模式的线程同步方法。但是,用户模式的线程同步有限制,对于多个进程之间的线程同步,用户模式的线程同步方法无能为力。这时,只能考虑使用内核模式。 用户模式与内核模式线程同步机制比较:

Super_Desk的博客 3025

Vue3项目实战:CKEditor5富文本编辑器从安装到隐藏不需要的功能

本文详细介绍了在Vue3项目中集成并深度定制CKEditor5富文本编辑器的完整流程。通过分析其模块化架构,指导开发者从标准构建出发,移除图片、表格等冗余插件,创建专属轻量构建,从而显著减小打包体积并提升用户体验。文章结合实战代码,涵盖了环境搭建、自定义构建配置、高级优化技巧等关键步骤。

weixin_29016833的博客 285

MsgWaitForMultipleObjects函数

MsgWaitForMultipleObjects函数该函数的特点是它不但可以等待内核对象,还可以等消息。也就是当有消息到来时,该函数也一样可以返回,并处理消息,这样就给了工作线程退出的机会。<br /><br />DWORD MsgWaitForMultipleObjects(<br />DWORD nCount, //要等待的内核对象数目<br />LPHANDLE pHandles, //要等待的内核对象句柄数组指针<br />BOOL fWaitAll, //是等待全部对象还是单个对象<br />D

fendouzhe的专栏 2039

Zemax热分析实战:5分钟搞定双胶合透镜温度漂移优化(附操作数详解)

本文详细解析了使用Zemax进行光学系统热分析的全流程,以双胶合透镜为例,重点阐述了如何通过多重结构编辑器模拟温度变化,并利用关键操作数优化系统以抵抗温度漂移。文章提供了从基础设置到高级优化的实战技巧,帮助工程师快速掌握无热化设计方法,确保系统在宽温范围内保持稳定成像性能。

n4o5p6q7r的博客 398

IDEA 2023最新破解教程:从安装到永久激活(附常见问题解决方案)

本文为Java开发者提供了一份详尽的IntelliJ IDEA 2023高效使用指南。内容涵盖从版本选择、安装配置到核心快捷键、项目依赖管理、高级调试测试以及插件生态的深度优化。旨在帮助用户在合法合规的前提下,充分发挥这款顶级IDE的潜力,显著提升Java开发效率与工作体验。

time3的博客 3373

MsgWaitForMultipleObjects和WaitForSingleObject的应用及其注意事项

MsgWaitForMultipleObjects()Waits until one or all of the specified objects are in the signaled state, an I/O completion routine or asynchronous procedure call (APC) is queued to the thread, or the time-out interval elapses. The array of objects can include

lzc881012的博客 1889

一文吃透 OData Deep Insert:从框架原理到 ABAP 实战

本文面向ABAP工程师,解析OData服务中的Deep Insert技术。文章首先阐述Deep Insert的业务背景,说明其适用于父子层级数据必须成组创建的场景(如销售订单与行项目)。随后深入框架实现机制,介绍SAP Gateway如何通过CREATE_DEEP_ENTITY方法处理嵌套请求,并强调开发者的责任边界。通过销售订单案例,文章对比了Deep Insert与$batch的适用场景差异,提供请求负载示例和DPC_EXT实现骨架代码。最后给出MPC_EXT声明深结构的三种套路,以及事务处理和错误处理

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 225

WaitForMultipleObject与MsgWaitForMultipleObjects用法

http://blog.youkuaiyun.com/byxdaz/article/details/5638680 用户模式的线程同步机制效率高,如果需要考虑线程同步问题,应该首先考虑用户模式的线程同步方法。  但是,用户模式的线程同步有限制,对于多个进程之间的线程同步,用户模式的线程同步方法无能为力。 这时,只能考虑使用内核模式。用户模式与内核模式线程同步机制比较  用户模式...

weixin_33939380的博客 477

从零开始创建Davinci Configurator配置工程

本文介绍了从零开始搭建达芬奇工程的详细步骤。首先安装Vector的CBD包后,通过DavicCFG.exe新建空白ECU工程。文章提到Postbuild相关概念可参考往期文章《AUTOSAR配置中的PostBuild、Precompile、Linktime》,并预告下期将讲解如何通过导入DBC文件来启用AUTOSAR模块。全文以实操截图为主,步骤清晰简明,适合开发者参考备份。

Xiaowestwind的博客 219

数据库系统工程师软考备战:第三篇 - SQL语言深入解析与应用

​​创建表​​​修改表​​​删除表​。

Programming Talk 122

delphi 中使用WaitForMultipleObjects等待线程执行,再执行后续代码

unit1 [delphi] view plain copy unit Unit1;      interface      uses     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,     Dialogs, StdCtrls;  

chinajobs的专栏 1261

【2026年米哈游春招 - 3月14日 -第一题- 行列相等】(题目+思路+Java&C++&Python解析+在线测试)

摘要 本文解决了一个矩阵行列和匹配问题:统计矩阵中行和等于列和的所有行列对数量。算法首先计算每行和每列的元素和,然后利用哈希表统计各行列和的出现次数。通过遍历列和并查询对应的行和出现次数,高效计算出匹配对数。该方法时间复杂度为O(nm),空间复杂度为O(n+m),适用于大规模矩阵数据。代码实现了Python、Java和C++版本,通过哈希表优化避免了暴力枚举,显著提高了计算效率。

m0_73659489的博客 83

在用户线程/主线程中推荐MsgWaitForMultipleObjects代替WaitForSingleObject和WaitForMultipleObjects()函数

多线程同步,采用WaitForSingleObject和WaitForMultipleObjects()函数出现卡死现象,采用MsgWaitForMultipleObjects代替可以解决此类问题。

cbNotes的专栏:不积硅步,无以至千里;不积小流,无以成江海! 7866

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

MFC 线程同步MsgWaitForMultipleObjects Function

1、作用 等待,直到一个或所有指定的对象处于信号状态或超时间隔过去。这些对象可以包括输入事件对象,您可以使用dwWakeMask参数指定这些对象。 2、函数原型 DWORD MsgWaitForMultipleObjects( [in] DWORD nCount, [in] const HANDLE *pHandles, [in] BOOL fWaitAll, [in] DWORD dwMilliseconds, [in] DWORD

qq_47999510的博客 798

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

在Delphi中WaitForMultipleObjects的使用

<br />procedure ThreadTest;stdcall; var Handles:TWOHandleArray; //Handle:THandle; Test:TTest; i:Integer; begin for i := 0 to 10 do begin Test := TTest.Create(False); Handles[i] := Test.Handle; end;

冷寒生读书笔记 3128

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

线程函数的设计以及MsgWaitForMultipleObjects函数的使用要点

使用多线程技术可以显著地提高程序性能,本文就讲讲在程序中如何使用工作线程,以及工作线程与主线程通讯的问题。 一 创建线程        使用MFC提供的全局函数AfxBeginThread()即可创建一个工作线程。线程函数的标准形式为 UINT MyFunProc(LPVOID );此函数既可以是全局函数,也可以是类的静态成员函数。之所以必须是静态成员函数,是由于类的非静态成员函数

Jinhill's Blog 1465

【MFC】主线程等待子线程退出函数(MsgWaitForMultipleObjects)

01、目录 目录01、目录02、函数介绍2.1 函数创建2.2 函数返回值2.3 函数使用事项03、示例04、小结 02、函数介绍 MsgWaitForMultipleObjects 功能:阻塞时仍可以响应消息,“对象被激发”或“消息到达队列”时被唤醒而返回 相关API:WaitForMultipleObjects(),此API接收到消息后不会被唤醒和返回。 MsgWaitForMultipleObjects()多接收一个参数,允许指定哪些消息是观察对象。 2.1 函数创建 DWORD MsgWait

Cain Xcy的博客 2534

MsgWaitForMultipleObjects 都做了什么

 MsgWaitForMultipleObjects and the queue state One danger of the MsgWaitForMultipleObjects function is calling it when there are already messages waiting to be processed, because MsgW

xiaofkg的专栏 461

MsgWaitForMultipleObjects_测试

1、个人感觉:   1.1、MSDN中(https://msdn.microsoft.com/en-us/library/ms684242.aspx),说: “ dwWakeMask[in]   The input types for which an input event object handle will be added to the array of object handl...

weixin_30716725的博客 604

[转]WaitForMultipleObject与MsgWaitForMultipleObjects用法

用户模式的线程同步机制效率高,如果需要考虑线程同步问题,应该首先考虑用户模式的线程同步方法。 但是,用户模式的线程同步有限制,对于多个进程之间的线程同步,用户模式的线程同步方法无能为力。这时,只能考虑使用内核模式。 用户模式与内核模式线程同步机制比较: 用户模式 内核模式 优点 线程同步机...

weixin_30892763的博客 428

Windows 应用偶现界面卡死问题的分析

我们开发的应用,在 Windows 平台上偶尔会卡死,不再响应任何鼠标事件。这样的现象不太容易出现,操作一天可能会出现一次。 在经过无数次重启应用,复现问题,断点调试,终于发现了一点端倪,并在各种排除法隔离一部分功能试验后,终于找到了罪魁祸首——一个几乎可以忽略的不合理参数。 特地在此记录一下,希望能够在某个时候帮助到某个同路人。 问题背景 首先,说明一下相关的软件背景。 我们使用的是一个第三方封装的 GUI 库,封装了 Windows 的窗口、窗口消息、GDI 等功能。这个库不是 Qt,而是一个

luansxx的专栏 2383

【MFC】 使用MsgWaitForMultipleObjects解决后台线程退出时SendMessage响应问题

问题 某些MFC后台线程可能在主程序退出时仍然处于工作状态。主程序退出前,一般需要等待后台线程先退出。处理这类问题的机制通常是,主程序在OnClose()函数中通过激活事件通知后台线程退出。 在这种情况下,后台线程退出时调用SendMessage()函数发送消息,主程序已不能响应。因为,此时主程序进入OnClose()函数后,消息响应机制已经关闭。 使用WaitForSingleObject...

sunriver2000的专栏 1643
上一篇: Windows下搭建Subversion 服务器
下一篇: C++实现反射机制(一)
雪岢奇
博客等级 码龄17年 310粉丝 60原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值