Threading problem

Hi,

I have a Windows Form and I need to create another thread to wait for an
input somewhere else in the program. When this happens, I will have to access
the form and modify it. Right now, this creates an error because I can't
access/modify the form from a thread that didn't create it.

I've searched through the reference and found that the ThreadPool class
allows me to "wait on behalf of other threads" but I haven't found a solution
with that yet. Does anyone know of a way to solve the problem

Thanks in advance,
Wing


Answer this question

Threading problem

  • Denham

    Thanks Mike! Greatly appreciated. I still have a few Questions:

    "yourForm.Invoke()" - this command goes in the Thread or on the Main form and as for declaring the delegate - that must be on the same form as the control is on which you wish to invoke/control

     

    sorry for being a bit slow... but there is no mention about how you tell what control on the form to invoke (or should the code be: "yourForm.lblSomeLabel.Invoke()")



  • Kaloyan Georgiev

    yes Smile

    in your thread code:


    yourForm.theUpdateMessage = "My Message";
    yourForm.Invoke(new DoDisplayCurrentStatusHandler(yourForm.UpdateStatus));

     



  • RudolfT

    I thought so. I tried that but i get an arguementoutofrange exception! (no innerexception or message)



  • MattTaylor

    Mike:

    how does that exactly work I cannot seem to grasp the idea at all :( i've tried searching all night long but examples dont make sense to me! I am in a similar situation:

    Main Form

    ClassA

    MainForm creates a thread and executes a method in ClassA
    ClassA will update a label text on Main Form
    MainForm has a method :




    public void UpdateStatusMessage(string theMessage)
    {
       this.lblStatus.Text = theMessage;
    }


     


    how do I use the Control Invoke method (im using .NET CF btw!)

  • SANDEEP MAMUNURI

    In .NET CF it will be a bit more complicated because it doesn't have an Invoke(delegate, args) which would have permitted you to pass arguments.

    First you need a delegate:


    // declare it somewhere outside of a class
    public delegate void UpdateStatusDelegate();

     

    then you need a method with a similar signature:


    // method that will be "invoked" in your form class
    public void UpdateStatus()
    {
       // code what you want to be run on the same thread as the control thread
    }

     

    next you can use Invoke:


    yourForm.Invoke(new UpdateStatusDelegate(yourForm.UpdateStatus));

     


    The only problem is that UpdateStatus cannot not have an argument. A solution can be to add a property to your form, let's say:



    public string MeesageToAdd { ... }

     


    and before you use Invoke you can set it to your message. Then in UpdateStatus you can read the mesage from this property.

    However, this works only if you have only one thread that does Invoke Sad.


  • DaveInCT

    Take a look at Control.Invoke/Control.BeginInvoke/Control.EndInvoke methods. It is that you need. They allow you to call a method using the thread that created the control instead of the current thread.


  • Swanand

    yourForm.Invoke() goes where you would have called UpdateStatusMessage so that means in the Thread.

    The delegate can be declared anywhere you like, including another file. A delegate is a type declaration like class, struct and enum are. Think to it as a class or struct having 2 fields: the "address" of the method you want to call (UpdateStatus in this case) and a reference to the object for which the method is called (yourForm in this case). If you know C/C++ this is the equivalent for a pointer to function/pointer to member.

    Regarding the control you invoke. In fact you "invoke" a method... not a control. Control is there for providing the thread on which the method is invoked. In most casese all the controls on a form are created by the same thread so yourForm.Invoke() or yourForm.lblSomeLabel.Invoke() are really the same thing: they call the method UpdateStatus of the object yourForm using the thread that created the form/control.


  • russ_mac

    hmmmm

    I think i kinda understand. I'm sorry...

    in my main form I have this:



    public string theUpdateMessage;
    public delegate void DoDisplayCurrentStatusHandler();

    ..
    ..
    public void UpdateStatus()
    {
       this.lblStatus.Text = this.theUpdateMessage;
    }

     



    but I still dont understand what to put in the thread class.

    would I set the "theUpdateMessage" variable in the thread class Then invoke the delegate

  • Threading problem