VB.NET Form.Show 从另一个线程挂起的窗体 [英] VB.NET Form.Show from another thread hanging form

查看:46
本文介绍了VB.NET Form.Show 从另一个线程挂起的窗体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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).

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

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_STATUS 的消息被触发时,我将登录表单中的一个函数分配给此单例类中定义的列表.

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.

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

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.

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

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.

希望这是有道理的.

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

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.

推荐答案

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

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

这篇关于VB.NET Form.Show 从另一个线程挂起的窗体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆