Link to home
Start Free TrialLog in
Avatar of axnst2
axnst2Flag for United States of America

asked on

Multi Threading and forms

Hi Experts,

     I have a form with a text box and a command button.  When the user presses the command button, I want to create two seperate instances of the same class and have them run on a thread of there own.  The threads will each come up with a random number between 1 and 10.  When the threads are done I want the form to take the two randomly generated numbers, add them up, and display the added value in the text box.

Something like this:

Form1.cs:
namespace MyNameSpace
{
           Public Partial Class MyForm : Form
           {
                      MyClass class1 = new MyClass;
                      MyClass class2 = new MyClass;
                     
                      class1.StartThread();
                      class2.StartThread();
           

                      Public void AddThem()
                      {
                                  txtBox.Text=class1.Result+class2.Result;
                      }

           }
}

MyClass.cs:
namespace MyNameSpace
{
           public class MyClass
           {
                      int RandNum;
                     
                      public int Result
                      {
                                 get
                                 {
                                              return RandNum;
                                  }
                                  set
                                  {
                                   }
                       }

                      public void StartThread()
                      {
                                 Thread t = new Thread(new ThreadStart(ThreadJob));
                                 t.IsBackground = true;
                                 t.Start();
                       }

                       private void ThreadJob()
                      {
                                 RandNum=GetRandomNum();
                                 myForm.AddThem();
                       }
}

What I am basically having problems with is how to call a function that only exists in the form's code from the class threads.  I know that in my example I could have a zero value for Class1.Result or Class2.Result depending on which thread finished first, but I am not worried about that for now.  I need the classes to be on their own threads so that the GUI is still functioning while my classes are coming up with the random numbers.  I know that in this example I wouldn't need to use mutliple threads, but this is just an example.  In reality ThreadJob takes about 30 seconds to execute.

Any help would be appreciated,

Thanks,
axnst2
Avatar of axnst2
axnst2
Flag of United States of America image

ASKER

Please also let me know if you think that I am just going about doing this completely the wrong way.

Thanks.
ASKER CERTIFIED SOLUTION
Avatar of AlexFM
AlexFM

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of AlexFM
AlexFM

Some explanations: MyClass defines event OnResultHandler which reports to subscriber result of thread calculation.
Form1 creates MyClass instances and subscribes to their OnResultHandler event.
OnResultHandler(RandNum) - this is actually call to class_OnResultHandler function.
class_OnResultHandler function is called in a worker thread context and cannot access directly form controls. It uses Invoke call which calls HandleResult function in the context of main application thread. By the way, using Invoke also solves the problem of thread safety.
Just for fun, it is possible to write one function which calls itself, and remove HandleResult function:

        void class_OnResultHandler(int result)
        {
            if ( this.InvokeRequired )
            {
                this.Invoke(new ResultHandler(this.class_OnResultHandler), new object[] { result });
            }
            else
            {
                int n = 0;

                try
                {
                    n = Int32.Parse(textBox1.Text);
                }
                catch (Exception)
                {
                }

                n += result;

                textBox1.Text = n.ToString();
            }
        }

See also:
http://www.codeproject.com/csharp/workerthread.asp
Avatar of axnst2

ASKER

Thanks Alex,  That worked great!