2010-07-25 65 views
0

我似乎遇到了線程問題。Thread和Form.Show()

首先讓我解釋一下應用程序是如何構建的。

我有一個擴展ApplicationContext的類,它是我整個應用程序的核心類,在這個類中我加載了新的窗口,例如登錄窗口。

然後每個窗口來回應用上下文類。

我有一個方法是用來打開一個新的消息窗口,在這裏。

public void InitiateChat(RosterItem Roster) 
     { 
      MessageWindow MessageWindow; 
      if (WindowManager.ContainsKey(Roster.Jid.Bare) == false) 
      { 
       MessageWindow = new MessageWindow(Roster); 
       MessageWindow.FormClosing += new FormClosingEventHandler(MessageWindow_FormClosing); 

       //Store it. 
       WindowManager.Add(Roster.Jid.Bare, MessageWindow); 
      } 
      else 
      { 
       MessageWindow = WindowManager[Roster.Jid.Bare]; 
      } 

      if (MessageWindow.InvokeRequired) 
      { 
       MessageWindow.BeginInvoke(new InitiateChatDelegate(InitiateChat), new Object[] { Roster }); 
       return; 
      } 

      if (MessageWindow.WindowState == FormWindowState.Minimized) 
      { 
       MessageWindow.WindowState = FormWindowState.Normal; 
      } 
      MessageWindow.Show(); 
      MessageWindow.Activate(); 
     } 

現在,當我在Messenger主窗口中運行從一個onclick事件下面的代碼,它工作正常:

RosterItem RosterItem = GetSelectedContact(); 
if (RosterItem != null) 
{ 
    Messenger.Bootload.MessengerApplication.Instnace.InitiateChat(RosterItem); 
} 

窗口作品完美,但因爲這是一個基於XMPP和信使應用agsXMPP我有一個事件女巫由AgsXMPP觸發,名爲OnMessage,女巫發給我一個通知,我有一個傳入消息。

這裏是該方法。

public void ClientConnection_OnMessage(Object Sender, agsXMPP.protocol.client.Message Message) 
{ 
    //Load the contacts Window 
    RosterItem RosterItem = ContactManager[Message.From.Bare]; 
    if (RosterItem != null) 
    { 
     InitiateChat(RosterItem); 
    } 
} 

的問題是,當我的消息出來我運行InitiateChat方法,但它凍結:(

其MessageWindow.Show()這就是不能運行良好

任何人可以幫我拿這個工作,我一直試圖做幾天現在

回答

4

你的OnMessage事件處理程序運行在後臺線程。這是常見的面向套接字的代碼。該線程的很多問題,它不運行消息循環並退出。有兩個原因t帽子使形式變得緊張。

您將不得不封送表單創建方法調用到UI線程。這通常是用Control.BeginInvoke()完成的。在你的情況下有點棘手,因爲你沒有一個明顯的Form對象來充當BeginInvoke提供者。你將不得不使用System.Threading.SynchronizationContext.Current.Post()。我會把它作爲一個練習,使用主窗口而不是ApplicationContext將是更簡單的路線。

+0

是的,我認爲儘可能多的關於後臺線程,所以基本上你的話是它不是我的應用程序類試圖設置形式其實後臺線程,我沒有線索關於當前。 Post()實體,請嘗試查看它。有沒有一些例子,你可以鏈接到關於從bg線程初始化/調用表單? - 你的信息非常有用 – RobertPitt 2010-07-25 17:58:37

+0

如果你真的必須使用Application.OpenForms [0] .BeginInvoke()。 – 2010-07-25 18:16:29

2
if (MessageWindow.InvokeRequired) 
    { 
     MessageBox.Show("Invoking Window"); 
     MessageWindow.BeginInvoke(new InitiateChatDelegate(InitiateChat), 
      new Object[] { Roster }); 
     return; 
    } 

您正在調用其他線程的MessageBox形式。這是行不通的。

只需用System.Diagnostics.Debug.Print()或類似的東西替換MessageBox.Show(...)即可。

+0

是的,Egnore MessageBox.Show()這是我只是測試,看看它是否是造成它的調用問題,但事實並非如此。這只是溫度 – RobertPitt 2010-07-25 17:59:29