我为网络代码调用了一系列方法。从网络线程触发事件。在我从单例类中挂钩的这个事件中,我将消息路由到表单级方法,它们在表单加载时注册以处理他们关心的某些消息。在这些表单消息钩子中,我需要关闭当前表单(我能够做到)但也显示不同的表单(这给我带来了麻烦)。
新形式的节目,但它是悬挂/不更新。我确定这与该表单有关,因为它的.Show()基本上是从另一个线程调用的(有点)没有消息循环,但我不知道如何解决这个问题。收到的网络消息在客户端计算机上指示要关闭和显示的表单。
流程可能令人困惑,所以我会更好地解释一下。
登录表单将该表单中的用户定义函数附加到单个类消息列表。例如,当一个名为LOGIN_STATUS的消息被触发时,我将一个函数从Login表单分配给这个singleton类中定义的列表。
单例类具有在其中定义的网络类,它实际上在另一个线程上运行,但这都是在类中处理的。在私有ctor中,我订阅了这个网络类的OnData事件。
当OnData从网络类触发到单例类时,它会向它传递数据类型。我遍历函数指针列表,看看是否有任何链接到LOGIN_STATUS,如果是,请调用它们。这将调用登录表单功能。在该函数内部,我需要关闭Login表单并打开Lobby表单。这是大堂表单显示的时间,但是挂起并且没有更新。
希望这是有道理的。
这一切都是在VB.NET中完成的,其中我有“关闭时关闭最后一个表单”设置,这就是我想要的。 VB.NET也使管理表单变得更容易,因为我可以只使用formname.Show()而不必保留表单列表并像C#一样自己管理它们,所以如果仍然可以使用理想的解决方案。
答案 0 :(得分:2)
如果要确保在同一个线程上创建所有表单,从而使用相同的消息循环,请使用main的Invoke方法。 Form.Invoke
和Form.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