2010-07-25 67 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