Welcome to weblogs.com.pk Sign in | Join | Help

Nasir Ali Khan

Believing is easier than thinking. Hence so many more believers than thinkers.
Dynamic Child Forms, an Intresting case study

Adding Dynamic Child Forms from Other Threads

Occurrence of unexpected errors and technical problems during the software development is very common and their solution takes lots of efforts and research. During the development of my academic project, I encountered such type of problem, after two days of research and work it solved. For the sake of exchanging information I like to share the problem and its solution with you people.

 

This is actually a client-server scenario in which server can serve request of multiple clients on TCP sockets. Server is basically an MDI application and one instance of child form represents a connected client. On client side every thing is fine so let’s discuss the server side issues.

 

Initially server is composed of two threads, one thread is listening request of socket and other manages the UI messages also called Main Thread. Main thread is responsible for creating the main form and creation of worker thread.

 

The Problem

When worker thread accepts a connection of a client, it needs to create a child form of main MDI form, solution is simple; i.e. what thread needs to do is to create a new form object and sets its MDIParent property to the Main MDI form. When I did this the exception comes ‘Controls created in one thread cannot be parented by controls created in other’.

 

I tried messages, events, delegates and other logics as well but problem didn’t solved because event delegates runs under the context of worker thread hence the problem occurs.

 

Following is the code snippet of this scenario

 

public class MainMDIForm : System.Windows.Forms.Form

{

      ... Rest of Form Declarations

 

      private Thread WorkerThread;

      private void MainMDIForm_Load(object sender, System.EventArgs e)

      {

WorkerThread = new Thread(

new ThreadStart(this.WorkerThreadProc));

            WorkerThread.Start();

      }

      private void WorkerThreadProc()

      {

            try

            {

                  Form child = new Form();

                  child.MdiParent = this;

                  child.Show();

            }

            catch (Exception e)

            {

                  MessageBox.Show(e.Message);

            }

      }

}

 

The Solution

Control.Invoke (…) method is the solution of this problem, this method always executes in the context of the thread in which control was created and this is what I want. Following is the solution of this scenario.

 

public class MainMDIForm : System.Windows.Forms.Form

{

      ... Rest of Form Declarations

 

      private Thread WorkerThread;

      private void Form1_Load(object sender, System.EventArgs e)

      {

            WorkerThread = new Thread(

new ThreadStart(this.WorkerThreadProc));

            WorkerThread.Start();

      }

 

      private void WorkerThreadProc()

      {

            try

            {

                  this.Invoke(new AddChildDelegate(this.AddChild));

            }

            catch (Exception e)

            {

                  MessageBox.Show(e.Message);

            }

      }

 

      private delegate void AddChildDelegate();

      private void AddChild()

      {

            Form child = new Form();

            child.MdiParent = this;

            child.Show();

      }

}

Posted: Tuesday, April 05, 2005 11:37 PM by nasir

Comments

No Comments

Anonymous comments are disabled