VB.NET Form.Show 从另一个线程挂起的窗体

发布于 2024-11-26 12:26:12 字数 769 浏览 0 评论 0原文

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

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

流程可能会令人困惑,所以我会尽力解释。

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

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

当 OnData 从网络类触发到单例类时,它会将数据类型传递给它。我循环遍历函数指针列表,查看它们中是否有任何链接到 LOGIN_STATUS,如果是,则调用它们。这将调用登录表单函数。在该函数内,我需要关闭登录表单并打开大厅表单。此时,大厅表单会显示,但已挂起且未更新。

希望这是有道理的。

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

I have a series of methods being called for my networking code. An event gets fired from the networking thread. Inside this event, which I've hooked into from a singleton class, I route messages to form level methods which they register on form load to handle certain messages they care about. Inside of these form message hooks I need to close the current form (which I was able to do) but also show a different one (which is giving me the trouble).

The new form sort of shows but it's hanging/not updating. I'm sure this has something to do with that form because it's .Show() was basically called from another thread (sort of) doesn't have a message loop, but I'm not sure how else to solve this. The network message that gets received indicates on the client machine what forms to close and show.

The flow might be confusing so I'll try better to explain.

Login form attaches user defined functions inside that form to a singleton class list of messages. For example when a message called LOGIN_STATUS is fired I assign a function from the Login form to a list defined in this singleton class.

The singleton class has the network class defined in it which actually runs on another thread, but this is all handled inside the class. In the private ctor I subscribe to the OnData event of this network class.

When OnData gets fired from the network class to the singleton class it passes to it the type of data. I loop through the list of function pointers to see if any of them are linked to LOGIN_STATUS and if so call them. This will call the Login forms function. Inside that function I need to close the Login form and open the Lobby form. That's when the Lobby form shows, but is hung up and not updating.

Hope that makes sense.

This is all being done in VB.NET where I have the "close when last form closed" setting on which is what I want. VB.NET also makes it easier to manage forms since I can just for formname.Show() instead of having to keep a list of the forms and manage them myself like in C# so if that's still possible with the solution that would be ideal.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

芸娘子的小脾气 2024-12-03 12:26:12

如果您想确保所有表单都在同一线程上创建,从而在同一消息循环上创建,请使用 main from 的 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

If you want to ensure all forms are created on the same thread, and hence the same message loop, use the main from's Invoke method. The Form.Invoke and Form.BeginInvoke methods cause the code to run from the form's message loop. BeginInvoke allows the event calling thread to return immediately, where-as Invoke blocks the event thread until the method is complete. It depends how time sensitive your code is.

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文