views:

309

answers:

4

I'm trying to write a chat client in C# and have run into a problem.

How it works is that the client polls the server every 1 second to see if there are any new actions to take (for example display a message in a channel, or whatever). The polling is done in a thread of its own.

Now, I want the polling thread to open a new MDI form when a channel open action is received (meaning the user has entered a new channel). The thing is, the new form should run on the MAIN program thread, and not on the worker thread.

So basically I'm asking, how do I create a new windows form, and associate it with an already existing thread? (instead of the thread that created it).

Also, if you know of a better way to do this, please tell me. I love improving my program architecture!

Thanks all

+4  A: 

Make the polling thread call back to the main form using Control.Invoke or Control.BeginInvoke, and create the form in the callback.

I assume you're already using Invoke/BeginInvoke to update the UI - this is just another kind of UI operation.

Jon Skeet
A: 

You should invoke the function from your main window:

    void MyWorkerThread() {
        while (Connected) {
            Thread.Sleep(1000);
            if (NewMessage) {
                ShowNewForm();
            }
        }
    }

    void ShowNewForm() {
        if (this.InvokeRequired) { // this refers to the current form
            this.Invoke(new Action(ShowNewForm));  // this line invokes the same function on the same thread as the current form
            return;
        }
        Form myMdiForm = new Form();
        myMdiForm.Show();
    }
Stormenet
I don't think there's really any need to make ShowNewForm thread-safe itself - just call Invoke (or BeginInvoke) from the worker thread method. This simplifies the code, IMO.
Jon Skeet
A: 

Stormenet: Thanks for the detailed reply. Unfortunately I am not sure how to relate it to my code, since the Worker Thread I have created does not open any form, it simply does some work. So when you do "this.InvokeRequired" in ShowNewForm(), I do not have an InvokeRequired method, since the methods are not sitting in a form class.

I hope this makes sense, I might not be explaining myself properly.

EdanB
The worker thread will need to have a reference to the form, and it can call the method that way.
Jon Skeet
A: 

Thanks guys, works like a charm!

EdanB