事件驱动编程 - 事件如何知道何时发生?

时间:2014-08-07 19:14:36

标签: event-driven


在过去的几周里,我一直非常关注软件中“幕后”发生的事情,有些事情让我感兴趣 - 事件驱动编程中的事件如何知道何时发生?
让我解释一下:假设我们在GUI中有一个按钮,按钮知道什么时候被按下了?是否有一个循环不断运行,一旦检测到按钮按下它就会激活事件或是否有更有效的方法?

3 个答案:

答案 0 :(得分:1)

它的工作方式基本上是当你单击鼠标按钮时,它会生成一个硬件中断,暂停当前正在执行的线程,并使操作系统运行一段特定的代码来处理这种类型的中断。在Windows中,这会导致生成一条消息,该消息将添加到正在运行的应用程序中的事件队列中。此时,中断处理硬件中断的线程将被恢复(或者可能是某个其他线程)。 GUI应用程序本质上是不断循环并检查此队列中的消息,当它获得消息时,它将通过执行诸如检查鼠标单击的x和y位置以查看是否在按钮的范围内以及是否在它会调用一些用户指定的代码(该按钮的单击事件处理程序)。所有这些通常被抽象到你只提供单击按钮时应该调用的代码。

答案 1 :(得分:1)

对于一个按钮,以及它如何知道它被点击,我只能说到Windows编程的经验,虽然我很确定它可以推断为涵盖其他类型的操作系统和窗口系统

操作系统Windows将密切关注输入设备,例如鼠标。当它检测到或者可能更恰当地被告知您单击其中一个鼠标按钮时,它会记录大量信息,然后搜索如何处理该信息。

我在这里猜测,但它可能是通过一个中断来告诉的,它会扼杀CPU并告诉它发生了一件特别的事情。

使用操作系统记录的信息,例如哪个鼠标,哪个按钮以及当时鼠标指针所在的位置,用于确定该信息会发生什么。

具体来说,Windows会尝试找出该窗口中哪个程序,窗口和组件应该被告知鼠标单击。当找到鼠标单击的位置时,它会将消息放入拥有该窗口的线程的消息队列中。

消息队列就像一个不断运行的循环,但只要没有发生任何事情就会停止,即。没有消息放入其队列时。因此,单击鼠标时创建的消息将被放入该线程的消息队列中,消息队列将获取该消息并对其进行处理。

消息队列循环看起来像这样:

Message msg;
while (GetNextMessage(out msg))
{
    ProcessMessage(msg);
}

在此处理它意味着线程指出消息应该进入窗口的哪个内部组件,然后调用该组件上的方法,为其提供消息。

所以基本上你的鼠标点击最终是对按钮对象的正常方法调用。

这就是它的全部内容。

在.NET中,有问题的方法名为WndProc。

现在,我们有什么事件驱动编程。什么是替代方案?

好吧,你可以做的一件事就是每次在窗口中需要一个新按钮时创建一个新的按钮类,嵌入当你点击该类中的按钮时应该发生的代码。

这会非常快,每次你需要一个新按钮时,你会一遍又一遍地做同样的事情。

事实上,唯一不同的是当您点击按钮时会发生什么。

因此,每次在程序中需要新按钮时,不要创建新按钮,而是制作一个可以执行所有操作的按钮类。

除此之外,那个班级怎么能做到一切?它不能,这就是为什么,当点击按钮时,它需要某种方式通知拥有的程序/窗口它被点击,这样就可以完成这个按钮的特定功能。

这就是创建事件的原因。您可以创建一个通用按钮类型,它将向外界(按钮类型之外)发出特定事物的信号,"事件"发生了,并不关心实际发生的事情。

答案 2 :(得分:0)

这里有两种不同的模型:

1 /该库控制了"事件循环" - 拦截用户事件,OS事件等,并依赖(用户定义的)回调机制来处理特定事件:(键盘,鼠标等)

2 /用户必须管理事件循环:检查事件,根据事件分派,并(通常)返回事件循环。

如果您能提供更多细节,将会有所帮助。