消息的分发与处理

The MailHub is a UI class which is responsible for routing messages from the UI, PSW, the keypad, etc… to multiple applets and modules developed using the VIA framework.  This is needed since applications do not have their own thread, and the VAL layer only sends messages to threads. 这是VIAMAILHUBC这个类的作用的描述。换而言之,它存在的价值是在单线程的体系下模拟了多线程的控制方式。实现的方式就是在32位的MSG ID中拿出一个位段(21-31)用于标志MSG所属的MAILBOX(CATIGORY),在分发消息之前先判断MSG的种类,然后发给合适的MAILBOX处理。

 

任何想要通过mailhub分发消息的mailbox,都必须有个注册的过程,其实质是将mailbox的指针加入到mailhubLinklistC成员变量mRegisteredMailboxes中,注销则是一个相反的过程,MailHub最多可以注册2^11个不同CATIGORYMAILBOX。只有注册了的MailboxMailhub才能辨别出属于它的MSG,并予以分发,这是一个遍历的过程。注册的过程在UITASK启动的时候就一一完成了。

 

MSG分发的Send方式与Post方式:

1.       Send方式:

用代码直接说明就很清楚,

……

Iterator = mRegisteredMailboxes.GetIterator();

  while ((MailboxP = (MailboxC*)mRegisteredMailboxes.GetNext(&Iterator)) !=

          NULL)

  {

    if (MailboxP->GetMailMask() & (1 << (GET_MAIL_CAT(MailMsgId)-1)))

      MailboxP->DeliverMail(MailMsgId, MailMsgP);

  }

……

整个过程就是,遍历,对比,然后调用相应的DeliverMail函数。这其中并没有通过消息队列,而是直接调用了消息的映射函数。对于这种方式,VIA的意见是:SendMail is a synchronous call and should be used with extreme caution in order to avoid deadlock issues.至于为什么会deadlock,原因还没有搞明白。但是显然,这种方式比POST方式要立竿见影也就是快得多,在某些刷屏的时候(特别是在手机而非FWP项目中),它们会有肉眼可辨的速度差异。

2.       Post方式:

浅显地说,这种方式与SEND方式相比,就是它不是直接根据MSG来调用相应 的映射函数,而是会将消息放入到消息队列中,交由OS控制。这样不会产生deadlock,但是OS可能会在比较晚的时候才来处理你想要更早处理的消息。有个折衷的方式是调用postpriorityMailmsg这一类的函数,它会让你的消息位于消息队列的最前端。令人奇怪的是,整套代码中没有人去调用这样的函数,人们倾向于在需要插队的时候干脆不去排队,也就是直接使用SEND方式。

如果仔细探究的话,我也许可以通过这种方式研究出OS是如何管理消息队列的,但是这显然应当是以后某个时候的任务。

对于这post方式,MSG只有WINDOW_CAT与非WINDOW_CAT的区别,这两类消息分别被发往不同的消息队列:前者给了EXE_MAILBOX_2_ID,而后者为EXE_MAILBOX_1_ID。至于它们是否在OS处理之后还经过细分,需要进一步研究。

 

MSG的处理,ProcessMail函数:

PostMailMsg这一类的函数是将MSG放入到消息队列中,而ProcessMail函数则是将MSG从消息队列中取出来,并加以处理(调用SendMailmsg函数)ProcessMail在一个死循环(UiTask函数)中被调用,以不断地检查消息队列中是否需要处理的消息,如果有,就拿出来处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C# 中,可以使用事件和委托来实现消息处理分发框架。具体地说,消息处理分发框架包括以下几个步骤: 1. 定义消息类型:首先需要定义消息的类型。可以使用类或结构体来表示消息消息中包含了需要传递的数据。 2. 声明委托类型:为了让消息处理程序能够注册到消息中心,需要声明一个委托类型,该委托类型包含了消息处理程序的签名。 3. 定义事件类型:使用事件来实现消息中心,需要定义一个事件类型,该事件类型包含了委托类型的实例。 4. 注册消息处理程序:消息处理程序需要注册到消息中心,即将其实例化,并将其添加到事件的委托列表中。 5. 发布消息:发送消息时,需要创建消息的实例,并将其作为参数传递给事件,事件会自动调用所有注册的委托来处理消息。 下面是一个示例代码,演示了如何实现消息处理分发框架: ```csharp // 定义消息类型 public class MyMessage { public string Data { get; set; } } // 声明委托类型 public delegate void MyMessageHandler(object sender, MyMessage message); // 定义事件类型 public class MessageCenter { public event MyMessageHandler MyMessageReceived; public void OnMyMessageReceived(MyMessage message) { MyMessageReceived?.Invoke(this, message); } } // 注册消息处理程序 public class MyMessageHandler1 { public void HandleMyMessage(object sender, MyMessage message) { Console.WriteLine($"MyMessageHandler1 received message: {message.Data}"); } } public class MyMessageHandler2 { public void HandleMyMessage(object sender, MyMessage message) { Console.WriteLine($"MyMessageHandler2 received message: {message.Data}"); } } // 发布消息 var messageCenter = new MessageCenter(); var handler1 = new MyMessageHandler1(); var handler2 = new MyMessageHandler2(); messageCenter.MyMessageReceived += handler1.HandleMyMessage; messageCenter.MyMessageReceived += handler2.HandleMyMessage; var message = new MyMessage { Data = "Hello, world!" }; messageCenter.OnMyMessageReceived(message); ``` 上述代码定义了一个 `MyMessage` 类型的消息,声明了一个委托类型 `MyMessageHandler`,并定义了一个 `MessageCenter` 类型的事件来实现消息中心。还定义了两个消息处理程序 `MyMessageHandler1` 和 `MyMessageHandler2`,它们实现了 `MyMessageHandler` 委托的签名。最后,通过将两个消息处理程序注册到事件中心,来处理 `MyMessage` 类型的消息

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值