2011-07-25 20 views
0

我有一系列的方法被稱爲我的網絡代碼。網絡線程會觸發事件。在這個事件中,我從一個單例類入手,我將消息路由到表單級別的方法,它們在表單加載時註冊以處理他們關心的某些消息。在這些表單消息鉤子的內部,我需要關閉當前表單(我能夠做到),但也顯示了不同的表單(這給我帶來了麻煩)。VB.NET Form.Show從另一個線程掛起形式

新的表格類型的節目,但它掛/不更新。我確信這與這種形式有關,因爲它的.Show()基本上是從另一個線程調用的(有點)沒有消息循環,但我不知道如何解決這個問題。收到的網絡消息在客戶端機器上指示關閉和顯示的形式。

流程可能會令人困惑,所以我會盡力解釋。

登錄表單將該表單中的用戶定義的函數附加到消息的單例類列表中。例如,當一個名爲LOGIN_STATUS的消息被觸發時,我將一個函數從登錄表單分配給這個單例類中定義的列表。

單例類具有在其中定義的網絡類,它實際上在另一個線程上運行,但是這是在類內部處理的。在私人ctor中,我訂閱了此網絡類的OnData事件。

當OnData從網絡類中被觸發到單例類時,它將它傳遞給它的數據類型。我遍歷函數指針列表來查看它們中的任何一個是否鏈接到LOGIN_STATUS,如果是,則調用它們。這將調用登錄表單功能。在該功能內部,我需要關閉登錄窗體並打開大廳窗體。這是大廳窗體顯示的時間,但掛起而不更新。

希望是有道理的。

這是所有正在VB.NET中完成的地方,我有「關閉當最後一個窗體關閉」設置在哪個是我想要的。 VB.NET也使管理窗體變得更容易,因爲我只需要formname.Show()而不必像C#那樣保留窗體列表並自己管理它們,所以如果仍然可以使用這種理想的解決方案。

回答

2

如果您希望確保所有表單都在同一個線程上創建,並因此創建了相同的消息循環,請使用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 
+0

這就是我正在做的,它仍然掛起。上面的方法我在模塊中有一個稍微修改過的版本(它非常類似)。然後我把它稱爲我想從輔助線程打開的表單,但是當我打開我的第二個窗體上的show時,我想打開InvokeRequired返回false,所以它直接調用.Show()直接導致它掛起。 – user441521

+0

哦,等等,你的意思是把OpenFormEvent()作爲一個方法放在UI線程上,然後從我的其他線程調用主線程上的OpenFormEvent(),因爲我直接從另一個線程調用窗體.Show()方法。也許我回家時會試試這個。 – user441521

+0

'Dim SecondForm As New Form()'在'MainForm'線程上被調用。這很重要!表單屬於它們創建的線程。 –