VB.NET Form.Show来自另一个线程挂起的表单

时间:2011-07-25 02:45:59

标签: vb.net thread-safety

我为网络代码调用了一系列方法。从网络线程触发事件。在我从单例类中挂钩的这个事件中,我将消息路由到表单级方法,它们在表单加载时注册以处理他们关心的某些消息。在这些表单消息钩子中,我需要关闭当前表单(我能够做到)但也显示不同的表单(这给我带来了麻烦)。

新形式的节目,但它是悬挂/不更新。我确定这与该表单有关,因为它的.Show()基本上是从另一个线程调用的(有点)没有消息循环,但我不知道如何解决这个问题。收到的网络消息在客户端计算机上指示要关闭和显示的表单。

流程可能令人困惑,所以我会更好地解释一下。

登录表单将该表单中的用户定义函数附加到单个类消息列表。例如,当一个名为LOGIN_STATUS的消息被触发时,我将一个函数从Login表单分配给这个singleton类中定义的列表。

单例类具有在其中定义的网络类,它实际上在另一个线程上运行,但这都是在类中处理的。在私有ctor中,我订阅了这个网络类的OnData事件。

当OnData从网络类触发到单例类时,它会向它传递数据类型。我遍历函数指针列表,看看是否有任何链接到LOGIN_STATUS,如果是,请调用它们。这将调用登录表单功能。在该函数内部,我需要关闭Login表单并打开Lobby表单。这是大堂表单显示的时间,但是挂起并且没有更新。

希望这是有道理的。

这一切都是在VB.NET中完成的,其中我有“关闭时关闭最后一个表单”设置,这就是我想要的。 VB.NET也使管理表单变得更容易,因为我可以只使用formname.Show()而不必保留表单列表并像C#一样自己管理它们,所以如果仍然可以使用理想的解决方案。

1 个答案:

答案 0 :(得分:2)

如果要确保在同一个线程上创建所有表单,从而使用相同的消息循环,请使用main的Invoke方法。 Form.InvokeForm.BeginInvoke方法导致代码从表单的消息循环中运行。 BeginInvoke允许事件调用线程立即返回,其中-Invoke阻塞事件线程,直到方法完成。这取决于您的代码的时间敏感程度。

Private Sub OpenFormEvent(sender As Object, e As EventArgs)
    If MainForm.InvokeRequired Then
        Dim args As Object() = {sender, e}
        MainForm.BeginInvoke(New EventHandler(AddressOf OpenFormEvent), args)
    Else
        Dim SecondForm As New Form()
        SecondForm.Show()
    End If
End Sub