VB.NET UserControl为什么MouseMove事件是异步的?

时间:2014-04-11 11:49:57

标签: vb.net user-controls mousemove

我在VB.NET中创建了一个usercontrol,我在MouseMove事件中做了一些相当耗时的事情。

我希望MouseMove事件排队。

但是我包含了一个陷阱,它告诉我MouseMove事件确实没有排队,而是我认为它是异步的。

Private _bInproc As Boolean = false

Private Sub ucGrid_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove

    If _bInproc Then
        Stop 'This should never be reached if MouseMove events were always queued, I think
     End If

    _bInproc = True

    doMousePointerMoveStuff(e.X, e.Y)

    _bInproc = False

End Sub

有没有人看到我本可以做的任何错误,或者是否有人知道它可能会像我的情况那样变得异步?

2 个答案:

答案 0 :(得分:2)

MouseMove等WinForm事件不是多线程(异步)。事件始终以串行方式在同一UI线程中引发。但是,仅当窗口消息循环(WndProc)引发事件时才会出现这种情况。这是引发事件的典型方式,但是您可以在自己的代码中使事件在第一个事件处理完毕之前重新引发。有几种方法可以实现。首先,从事件处理程序中,您可以递归调用相同的事件处理程序方法。其次,从事件处理程序中,您可以再次引发相同的事件,这将导致立即再次调用事件处理程序。第三,您可以调用DoEvents,这将导致消息循环立即处理所有可能再次引发相同事件的排队窗口消息。所有这些都令人困惑和意外,所以我不鼓励做任何这些事情。这是DoEvents如此沮丧的主要原因之一。为了弄清楚调用它的位置,只需在事件处理程序中放置一个断点,并在每次调用时查看调用堆栈。

答案 1 :(得分:0)

WinForms中的事件永远不会异步,它们总是发生在UI线程上。这就是您可以更改其他控件的原因。其中的属性。否则,您将获得跨线程操作例外。

现在因为它们与UI线程同步,所以不能有任何事件队列。您无法从UI线程发送另一个事件,即移动鼠标,因为UI线程当前正在处理事件处理程序。

您可以拥有自己的异步事件处理程序,在这种情况下,您负责处理其中的线程同步。

希望它有意义。如果没有,请在下面的评论中提问。