weitom1982

向各位技术前辈学习,学习再学习.
posts - 299, comments - 79, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

事件和回调 (转贴)

Posted on 2006-03-20 16:32 高山流水 阅读(388) 评论(0)  编辑 收藏 引用 所属分类: 程序语言
 

事件和回调


Ken Bergmenn
MSDN开发组

什么时候使用一个事件(或连接点)接口以及什么时候使用特定的回调接口是很难理解的。他们有点类似,但在很多方面还是有很大的差异。下面将概述一些基本问题,这些基本问题在试图决定如何继续进行你的组件时是应该考虑到的。

我认识你吗?

事件接口和回调接口之间关键的概念差异是事件被设计得更象一个匿名广播,而回调函数则更象一个"握手"联络方式。虽然其他重要问题也需要阐明,但是关于使用哪一个技术关键决定于匿名性。

开始熟悉

任意对一个事件源有访问的对象都能通过简单地把那个索引放进WithEvents变量来处理源提出的事件。在C++中处理连接点与之有相当的关联,但是前提是一样的。在任意一种情况下,事件源对什么对象可能正在处理自己的事件没有任何概念。可能有许多个对象正与之密切相连但也可能一个也没有。关键之处是事件源盲目地通知每一个被连接的客户机通过它的事件连接点接口,但并不知道是否客户机正在执行处理事件。

相反地,一个设计用来执行回调的服务器必须有一个明显的对每个需要通知的对象的访问,它必须连接和管理这些访问,而且最后它还必须执行通知。基本上,服务器必须清楚地知道有多少个客户机以及如何与他们中的每一个连接和交互。

事件顺序

在Microsoft Visual Basic事件接口中,一个事件源不能控制客户机接受他们的事件的顺序。这话反之也是正确的。客户机不能肯定与别的客户机相比用一种特定的顺序接受通知。即使你要在C++中滚动你自己的连接点,后者也是正确的。

另一方面,一个回调服务器必须控制它调回客户机的顺序。当然,在一个回调服务器上做这些工作会有好处。比如,一个源服务器可能被设计用来给某些客户机高优先级的通知,或它可能执行一些特定的基于回调结果的动作。这个灵活性在下一点中将更有意义。

谁负责

当事件服务器提出一个事件,它的所有的客户机都得到了在事件服务器能重新得到控制之间处理事件的机会。所以,如果许多客户机都在听候事件,通知处理将花费难以预知的时间。另一方面,一个回调服务器,因为它对执行通知处理负责,所以在它对客户机做的每个调用它都能重新得到控制。

因为控制级别在这里是有效的,回调可以采用比事件更灵活的技术来进行客户通知。

现在,让我们来考虑一下事件的参数会发生什么变化。因为事件服务器直到所有的客户机都已经处理了特定的事件后才能重新得到控制,所有特定客户机的ByRef参数的变化已经丢失了。只有最后一个客户机参数发生的变化能被事件服务器看见。当考虑到哪一个客户机被通知的顺序不能得到保证的事实时,这确实变得不方便。当然,对于回调服务器,服务器对这个处理负责,所有每一个客户机的反馈都能被独立地分析。事实上,一个回调服务器可能希望在通知每一个客户机时传递新值。

处理错误

两种途径之间最终的编译差异在于错误的处理方式。如果在一个客户机的事件处理器中发生了错误,则事件源不会被通知。处理事件的客户机甚至可能非常可怕地崩溃掉,而事件源并不知道,当然,客户机的致命错误也只能是使服务器崩溃(如果它是一个处理中的元件)。在这种情况中,事件服务器将不知道为什么崩溃,甚至不知道发生了错误。

当然,在任意执行问题中,测量你自己的需要的唯一办法是实验,基准和测试。你自己可以试试重排列,并作作数学演算。如果你真的想得到绝对的最后速度冲刺,那么做测试是得到保证的唯一方法,而不能相信你曾经得到什么样的承诺。

只有注册用户登录后才能发表评论。