2012-04-14 105 views
1

我的問題有點複雜:調用窗體並凍結

我有Socket服務器,我有兩種形式。一個是服務器的主要形式,另一個是定製的消息框。當請求到達服務器時,主表單必須調用第二個表單(messagebox)。當主窗體首次打開時,一切正常。但是,當我關閉的主要形式,但不關閉應用程序,然後再次打開它,並請求進入到服務器的定製消息框打開,但它凍結,看起來像這樣:

enter image description here

的代碼調用:

Private Delegate Sub DInvoke(ByRef Frm As Form, ByVal Text As String, ByVal Title As String, ByVal Socket As Integer, ByVal DataX As String, ByVal ReqForProfil As Boolean) 

Public Sub ShowMessage(ByRef Frm As Form, ByVal Text As String, ByVal Title As String, ByVal Socket As Integer, ByVal DataX As String, ByVal ReqForProfil As Boolean) 
    If Frm.InvokeRequired Then 
     Dim DT As New DInvoke(AddressOf ShowMessage) 
     Frm.Invoke(DT, New Object() {Frm, Text, Title, Socket, DataX, ReqForProfil}) 
    Else 
     Messegar = New MessageFrm(Text, Title, Socket, DataX, ReqForProfil, True, 30) 
     Messegar.Show() 
    End If 
End Sub 

任何幫助,將不勝感激!

回答

4

調試它。在InvokeRequired上設置一個斷點。你知道它應該是真的,因爲該方法是從I/O完成線程調用的。您描述的問題與返回False的屬性一致。所以調用不會發生,並且表單在工作線程而不是UI線程上創建了。因爲該線程不是抽取消息循環,所以它作爲門衛死了。

這通常是由傳遞一個錯誤的表單對象造成的。像「Form1」,一種類型而不是一個對象,一個討厭的VB.NET陷阱。或者傳遞「新Form1」,這是表單對象的一個​​新實例,而不是用戶正在查看的新實例。

A Q & D修正是通過Application.OpenForms(0)來代替。一個簡單的解決方法是將有效的表單引用傳遞給與套接字配合使用的類的構造函數。

+0

感謝Hans Passant的幫助。 Application.OpenForms解決了我的凍結問題。 – 2012-04-14 15:51:08