用SendNotifyMessage代替PostMessage避免消息丢失(WIN7下消息队列的默认长度是10000,队列满后消息将被丢弃)

大家都知道PostMessage会丢消息,但是消息队列的大小是多少呢,下面做了一个测试。

代码:

 1 unit Unit1;
 2
 3 interface
 4
 5 uses
 6   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 7   Dialogs, StdCtrls;
 8
 9 const
10   UM_ADD = WM_USER + 100;
11
12 type
13   TForm1 = class(TForm)
14     Label1: TLabel;
15     procedure FormCreate(Sender: TObject);
16   private
17     FVal: Integer;
18     procedure OnMsgAdd(var Msg: TMsg); message UM_ADD;
19   public
20     { Public declarations }
21   end;
22
23 var
24   Form1: TForm1;
25
26 implementation
27
28 {$R *.dfm}
29
30 procedure TForm1.FormCreate(Sender: TObject);
31 var
32   i: Integer;
33 begin
34   for i:=0 to 1000000 do
35     PostMessage(Handle, UM_ADD, 0, 0);
36 end;
37
38 procedure TForm1.OnMsgAdd(var Msg: TMsg);
39 begin
40   Inc(FVal);
41   Label1.Caption := IntToStr(FVal);
42 end;
43
44 end.

XP下运行结果:

可见,消息队列的默认长度是10000(在WIN7下运行结果是9998),队列满后消息将被丢弃。

如果把代码中的PostMessage改成SendNotifyMessage,运行后过了一段时间,窗口弹出:

所以,功能类似的SendNotifyMessage不会丢掉消息,必要时可以用它代替PostMessage。

上面的结论是错误的,SendNotifyMessage并没有那么神奇,上面的例子没有丢失消息的原因是因为

SendNotifyMessage发消息给同线程创建的窗口时,采用的是直接调用窗口函数的方式,换句话说

就是在执行SendMessage。

http://www.cnblogs.com/ddgg/archive/2013/03/31/2991595.html

时间: 2024-08-04 23:52:26

用SendNotifyMessage代替PostMessage避免消息丢失(WIN7下消息队列的默认长度是10000,队列满后消息将被丢弃)的相关文章

【MySQL】Win7下修改MySQL5.5默认编码格式

一般安装MySQL程序过程中,有一步骤是选择MySQL的默认编码格式的,程序默认为Latin1编码格式,当然也可以选择第三个选项,手动选择gbk或utf8编码格式,以支持中文数据.如下图: 现在问题出来了,安装完成后,又想去修改MySQL的默认编码格式(这样就省去每次新建数据库都要指定其编码格式的麻烦),该怎么办呢? 1:如何查看MySQL相关的编码格式默认值 在cmd中,输入指令"mysql –u root –p”以root身份连接mysql数据库 然后有两种方式查看编码格式: 1)show

win7下万能跨进程PostMessage/SendMessage

typedef BOOL (WINAPI *_ChangeWindowMessageFilter)( UINT , DWORD); BOOL AllowMeesageForWin7(UINT uMessageID, BOOL bAllow)//注册Win7全局消息 { BOOL bResult = FALSE; HMODULE hUserMod = NULL; hUserMod = LoadLibrary( _T("user32.dll") ); if( NULL == hUserMo

WM_PAINT消息详解,使用InvalidateRect或InvalidateRgn函数刻意产生WM_PAINT消息(WIN7里有变化,“调整视觉效果”,将“启用桌面组合”去掉)

什么时候会触发WM_PAINT消息消息呢? 以下内容来自大名鼎鼎的<Windows程序设计(第五版)> 大多数Windows程序在WinMain中进入消息循环之前的初始化期间都要呼叫函数UpdateWindow.Windows利用这个机会给窗口消息处理程序发送第一个WM_PAINT消息.这个消息通知窗口消息处理程序:必须绘制显示区域.此后,窗口消息处理程序应在任何时刻都准备好处理其它WM_PAINT消息,必要的话,甚至重新绘制窗口的整个显示区域.在发生下面几种事件之一时,窗口消息处理程序会接收

RabbitMQ-从基础到实战(2)— 防止消息丢失

未经允许,禁止转载! 1.简介 RabbitMQ中,消息丢失可以简单的分为两种:客户端丢失和服务端丢失.针对这两种消息丢失,RabbitMQ都给出了相应的解决方案. 2.防止客户端丢失消息 如图,生产者P向队列中生产消息,C1和C2消费队列中的消息,默认情况下,RabbitMQ会平均的分发消费给C1C2(Round-robin dispatching),假设一个任务的执行时间非常长,在执行过程中,客户端挂了(连接断开),那么,该客户端正在处理且未完成的消息,以及分配给它还没来得及执行的消息,都将

rabbitmq 重复ACK导致消息丢失

rabbitmq 重复确认导致消息丢失 背景 rabbitmq 在应用场景中,大多采用工作队列 work-queue的模式. 在一个常见的工作队列模式中,消费者 worker 将不断的轮询从队列中拉取最新消息,当队列负载压力增大时允许添加多个worker 进行处理.然而执行一个任务可能需要相当的时长,这是由业务特性所决定的:如果 worker执行任务过程中出现异常甚至宕机,此时消息便会丢失,这是简单消息队列难以解决的问题. rabbitmq 采用了消息确认机制来防止此类问题,在该机制中,work

openfire在网络不好或掉线时消息丢失的处理方法

在服务端收到消息后增加如下代码 //保存到离线消息表,客户端收到后调用删除离线消息功能,这样可确保即使网络突然掉线或不好的情况下消息丢失的问题 OfflineMessageStore offlineMessageStore = new OfflineMessageStore(); offlineMessageStore.addMessage(message); 客户端在登录的时候要先设置为离线,收完离线消息后再改成在线模式. 接收方在收到每条消息后自己调用删除离线消息. 注意事项: 1.登录前要

RabbitMQ,为应对消息从发送到消费,各个环节消息丢失的解决方案

1.发送方   为保证消息到达exchange,在这个过程中不丢失.  用事务或者发送方确认机制  见<RabbitMQ实战指南>4.8节 2.为保证消息不会因为到达exchange后,无法路由到任何一个队列而丢失 解决方案一:发送方发送消息时 令mandatory参数=true,用ReturnListener异步接收没有任何队列接收而返回给发送方的消息.  见<RabbitMQ实战指南>4.1.1节 解决方案二:给exchange指定一个备份交换器及对应队列,到达交换器的消息如何

Kafka在高并发的情况下,如何避免消息丢失和消息重复?kafka消费怎么保证数据消费一次?数据的一致性和统一性?数据的完整性?

1.kafka在高并发的情况下,如何避免消息丢失和消息重复? 消息丢失解决方案: 首先对kafka进行限速, 其次启用重试机制,重试间隔时间设置长一些,最后Kafka设置acks=all,即需要相应的所有处于ISR的分区都确认收到该消息后,才算发送成功 消息重复解决方案: 消息可以使用唯一id标识 生产者(ack=all 代表至少成功发送一次) 消费者 (offset手动提交,业务逻辑成功处理后,提交offset) 落表(主键或者唯一索引的方式,避免重复数据) 业务逻辑处理(选择唯一主键存储到R

MQ在高并发环境下,如果队列满了,如何防止消息丢失?

1.为什么MQ能解决高并发环境下的消息堆积问题? MQ消息如果堆积,消费者不会立马消费所有的消息,不具有实时性,所以可以解决高并发的问题. 性能比较好的消息中间件:Kafka.RabbitMQ,RocketMQ. 2.什么情况下会产生消息丢失的现象? 消息队列满了的情况下. 3.如何解决消息丢失的问题? (1)生产者可以采用重试机制.因为消费者会不停的消费消息,可以重试将消息放入队列. 如果还是不行,可以将消息记录到数据库,后期做补偿.(不太推荐,不方便) (2)死信队列,可以理解为备胎.(推荐