2010-07-25 13 views
0

Je semble avoir des problèmes avec Threading.Thread et Form.Show()

D'abord, laissez-moi vous expliquer comment l'application est construite.

J'ai une classe qui étend ApplicationContext, qui est ma classe de base pour l'ensemble de l'application, au sein de cette classe, je charge de nouvelles fenêtres telles que la fenêtre de connexion.

puis chaque fenêtre parle dans la classe de contexte d'application.

J'ai une méthode qui est utilisée pour ouvrir une nouvelle fenêtre de message, la voici.

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(); 
     } 

Maintenant, quand je lance le code suivant d'un événement OnClick dans la fenêtre principale de Messenger, il fonctionne très bien:

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

La fenêtre fonctionne parfaitement, mais cela est une application de messagerie basé sur XMPP et agsXMPP J'ai un événement qui est déclenché par agsXMPP appelé OnMessage, qui m'envoie une notification que j'ai un message entrant.

Voici la méthode.

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); 
    } 
} 

Le problème est que lorsque je sort un message que je lance la méthode InitiateChat mais il gèle :(

Son MessageWindow.Show le() des thats cant fonctionnent très bien

Quelqu'un peut-il me aider Cela fonctionne, je l'ai essayé depuis quelques jours maintenant

Répondre

4

Le gestionnaire d'événement OnMessage s'exécute sur un thread d'arrière-plan, ce qui est courant avec le code orienté socket. lancer une boucle de message et il sort. Le chapeau rend la forme catatonique.

Vous devrez marshaler l'appel de la méthode de création de formulaire au thread de l'interface utilisateur. C'est normalement fait avec Control.BeginInvoke(). Un peu compliqué dans votre cas puisque vous n'avez pas d'objet Form évident pour agir en tant que fournisseur BeginInvoke. Vous devrez utiliser Monkey avec System.Threading.SynchronizationContext.Current.Post(). Je vais laisser cela comme un exercice, en utilisant une fenêtre principale au lieu d'un ApplicationContext serait le chemin le plus facile.

+0

Oui, je pensais autant en ce qui concerne le fil de fond, donc fondamentalement votre affirmation n'est pas ma classe Application qui essaie de mettre en place la forme son fil de fond, je n'ai pas la moindre idée sur le courant. Post() entité, mal essayer de le regarder. N'y at-il pas quelques exemples que vous pouvez me lier en ce qui concerne l'initialisation/l'invocation d'un formulaire à partir d'un fil bg? - votre information est très utile – RobertPitt

+0

Utilisez Application.OpenForms [0] .BeginInvoke() si vous le devez vraiment. –

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

Vous appelez l'objet MessageBox de l'autre thread. Cela ne marchera pas.

Il suffit de remplacer le MessageBox.Show(...) par System.Diagnostics.Debug.Print() ou quelque chose de similaire.

+0

Oui, Egnore MessageBox.Show() c'était moi juste de tester pour voir si c'était le problème d'Invoke le provoquant, mais ce n'était pas le cas. c'était jsut temp – RobertPitt