views:

82

answers:

2

I seem to be having trouble with Threading.

First let me explain how the application is built.

I have a class that extends ApplicationContext, witch is my core class for the whole application, within this class I load new windows such as the login window.

then each window talks back and forth to the application context class.

I have a method that is used to open a new message window, here it is.

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

Now when I run the following code from an OnClick event in the main messenger window it works fine:

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

The window works perfectly, but as this is a messenger application based on XMPP and agsXMPP i have an event witch is triggered by agsXMPP called OnMessage, witch sends me a notification that I have an incoming message.

here is that method.

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

The problem is that when I message comes out I run the InitiateChat method but it freezes :(

Its the MessageWindow.Show() thats cant run fine

Can anybody help me get this to work, I'v been trying to do it for a few days now.

+4  A: 

You OnMessage event handler runs on a background thread. That's common with socket oriented code. Lots of problems with that thread, it doesn't run a message loop and it exits. Two reasons that make the form go catatonic.

You'll have to marshal the form creation method call to the UI thread. That's normally done with Control.BeginInvoke(). A bit tricky in your case since you don't have an obvious Form object to act as the BeginInvoke provider. You'll have to monkey with System.Threading.SynchronizationContext.Current.Post(). I'll leave that as an exercise, using a main window instead of a ApplicationContext would be the easier route.

Hans Passant
Yea I thought as much in regards to the background thread, so basically waht your saying is its not my Application class thats trying to set up the form its actually the background thread, I haven't got a clue about the Current.Post() entity, ill try look into it. is there not some examples that you can link me to in regards to initializing / invoking a form from a bg thread ? - your information is very helpfull
RobertPitt
Use Application.OpenForms[0].BeginInvoke() if you really have to.
Hans Passant
+2  A: 
   if (MessageWindow.InvokeRequired)
   {
       MessageBox.Show("Invoking Window");
       MessageWindow.BeginInvoke(new InitiateChatDelegate(InitiateChat), 
           new Object[] { Roster });
       return;
   }

You are calling the MessageBox form the other Thread. That won't work.

Just replace the MessageBox.Show(...) with System.Diagnostics.Debug.Print() or something similar.

Henk Holterman
Yea, Egnore MessageBox.Show() that was me just testing to see if it was the Invoke issue causing it, but it was not. it was jsut temp
RobertPitt