Istrebitel
Istrebitel

Reputation: 3083

C# Control.Invoke a method group

I am using threads to run long operations in my program's UI so that it doesn't lock up. However, in those tasks I need to update controls, which is impossible not from the thread they were created on. It is suggested to use control.BeginInvoke(Delegate) to execute the method you want.

However, to do that you have to declare a delegate type and only then you can call them.

So, it goes like this: if I want to execute method void Update(), i have to go:

delegate void CallbackVoid();
void Update() {...}

...(in task code)...
this.BeginInvoke(new CallbackVoid(Update));

This is rather tiresome to do for every single method out there. Can't I just somehow do it naturally, like:

void Update() {...}    
this.BeginInvoke(Update);

Upvotes: 2

Views: 657

Answers (4)

Alex
Alex

Reputation: 8937

UPDATED: WORKS FOR WPF!!!

You can use short syntax with anonymous methods, without even declaring your methods

  Dispatcher.BeginInvoke(DispatcherPriority.Background, new MethodInvoker(() =>   
                {
                   //Your Update code
                }));

Upvotes: 1

Denise Skidmore
Denise Skidmore

Reputation: 2416

BeginInvoke is asynchronous, Invoke is synchronous, which one you use depends on what you're trying to do. If you need the call to complete before you move on, then you want synchronous calls.

Here's my favorite construct for synchronous invokes:

 static void InvokeIfRequired(Control control, Action action)
 {
    if (control.InvokeRequired)
    {
        control.Invoke(action);
    }
    else
    {
        action.Invoke();
    }
 }

Used:

void MyTestFunction()
{
    InvokeIfRequired(myControl, () =>
        {
            MyFunction();
            MyOtherFunction();
        });

    // Or more simply:
    InvokeIfRequired(myControl, () => MyFunction());
}

There is a little overhead in the creation of the Action, but it simplifies the code quite a bit to not have to think about the details everywhere.

Upvotes: 0

Max
Max

Reputation: 13328

Try the following:

    if (this.controlname.InvokeRequired && !this.controlname.IsDisposed)
                {
                    Invoke(new MethodInvoker(delegate()
                        {
                            //Update control on GUI here!

    }));
    else if(!this.controlname.IsDisposed)
   {
                           //AND here!
   }

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1499740

One option which simplified things is to add an extension method:

public static void BeginInvokeAction(this Control control, Action action)
{
    control.BeginInvoke(action);
}

Then you can just use:

this.BeginInvokeAction(action);

The reason this works is that we're now providing a concrete delegate type for the compiler to convert the method group to.

Upvotes: 2

Related Questions