What's the difference between Invoke() and BeginInvoke()

33

Solution 1

Do you mean Delegate.Invoke/BeginInvoke or Control.Invoke/BeginInvoke?

  • Delegate.Invoke: Executes synchronously, on the same thread.
  • Delegate.BeginInvoke: Executes asynchronously, on a threadpool thread.
  • Control.Invoke: Executes on the UI thread, but calling thread waits for completion before continuing.
  • Control.BeginInvoke: Executes on the UI thread, and calling thread doesn't wait for completion.

Tim's answer mentions when you might want to use BeginInvoke - although it was mostly geared towards Delegate.BeginInvoke, I suspect.

For Windows Forms apps, I would suggest that you should usually use BeginInvoke. That way you don't need to worry about deadlock, for example - but you need to understand that the UI may not have been updated by the time you next look at it! In particular, you shouldn't modify data which the UI thread might be about to use for display purposes. For example, if you have a Person with FirstName and LastName properties, and you did:

person.FirstName = "Kevin"; // person is a shared reference
person.LastName = "Spacey";
control.BeginInvoke(UpdateName);
person.FirstName = "Keyser";
person.LastName = "Soze";

Then the UI may well end up displaying "Keyser Spacey". (There's an outside chance it could display "Kevin Soze" but only through the weirdness of the memory model.)

Unless you have this sort of issue, however, Control.BeginInvoke is easier to get right, and will avoid your background thread from having to wait for no good reason. Note that the Windows Forms team has guaranteed that you can use Control.BeginInvoke in a "fire and forget" manner - i.e. without ever calling EndInvoke. This is not true of async calls in general: normally every BeginXXX should have a corresponding EndXXX call, usually in the callback.

Solution 2

Building on Jon Skeet's reply, there are times when you want to invoke a delegate and wait for its execution to complete before the current thread continues. In those cases the Invoke call is what you want.

In multi-threading applications, you may not want a thread to wait on a delegate to finish execution, especially if that delegate performs I/O (which could make the delegate and your thread block).

In those cases the BeginInvoke would be useful. By calling it, you're telling the delegate to start but then your thread is free to do other things in parallel with the delegate.

Using BeginInvoke increases the complexity of your code but there are times when the improved performance is worth the complexity.

Solution 3

The difference between Control.Invoke() and Control.BeginInvoke() is,

  • BeginInvoke() will schedule the asynchronous action on the GUI thread. When the asynchronous action is scheduled, your code continues. Some time later (you don't know exactly when) your asynchronous action will be executed
  • Invoke() will execute your asynchronous action (on the GUI thread) and wait until your action has completed.

A logical conclusion is that a delegate you pass to Invoke() can have out-parameters or a return-value, while a delegate you pass to BeginInvoke() cannot (you have to use EndInvoke to retrieve the results).

Solution 4

Just to give a short, working example to see an effect of their difference

new Thread(foo).Start();

private void foo()
{
  this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
    (ThreadStart)delegate()
    {
        myTextBox.Text = "bing";
        Thread.Sleep(TimeSpan.FromSeconds(3));
    });
  MessageBox.Show("done");
}

If use BeginInvoke, MessageBox pops simultaneous to the text update. If use Invoke, MessageBox pops after the 3 second sleep. Hence, showing the effect of an asynchronous (BeginInvoke) and a synchronous (Invoke) call.

Solution 5

Delegate.BeginInvoke() asynchronously queues the call of a delegate and returns control immediately. When using Delegate.BeginInvoke(), you should call Delegate.EndInvoke() in the callback method to get the results.

Delegate.Invoke() synchronously calls the delegate in the same thread.

MSDN Article

Share:
33
Ramzy Abourafeh
Author by

Ramzy Abourafeh

Updated on July 15, 2022

Comments

  • Ramzy Abourafeh
    Ramzy Abourafeh almost 2 years

    I've ParentDirective inside it I've ChildDirective, I defined array in the scope of the ParentDirective, and it's bound the view of the ChildDirective, but I notice that when I debugged the code, that the debugger reached to the link of the ChildDirective before the link of the ParentDirective, and it cause that it don't display anything in the view.

    How can I fixed it?

    • thomaux
      thomaux about 10 years
      Please post some code as well, preferably a runnable example like a Fiddle or Plunkr.
  • loverboy
    loverboy over 14 years
    I'm confused by "Control.Invoke: Executes on the UI thread, but calling thread waits for completion before continuing. Control.BeginInvoke: Executes on the UI thread, and calling thread doesn't wait for completion" I don't think Control.Invoke/BeginInvoke executes on the UI thread, they should execute on the thread that owns the Control's handle.( which is not always the UI thread ). See MSDN
  • yeeen
    yeeen over 13 years
    Then why would ppl use Invoke over BeingInvoke? Shouldn't there be some advantages over using Invoke. Both executes processes in the background, just that one is on the same thread, the other on different thread?
  • SharpUrBrain
    SharpUrBrain about 13 years
    @Jon: While I am using Dispatcher.BeginInvoke my code is working fine and in Dispatcher.Invoke my application making me wait for few seconds then it initializes all controls then launching, Can you please help me to find out exactly in which place I stuck ?
  • SharpUrBrain
    SharpUrBrain about 13 years
    @All: Can anybody give a brief idea on Dispatcher.BeginInvoke and Dispatcher.Invoke ? How they works and what they doing, everything.
  • Jon Skeet
    Jon Skeet about 13 years
    @SharpUrBrain: Well, what have you read, and which bits didn't you understand?
  • SharpUrBrain
    SharpUrBrain about 13 years
    @Jon I am very new to .net Framework and I never used this Dispatcher class, Here you told something about Control.BeginInvoke. Is that same as Dispatcher.BeginInvoke?
  • Jon Skeet
    Jon Skeet about 13 years
    @SharpUrBrain: Control.BeginInvoke is sort of the equivalent of Dispatcher.BeginInvoke, but for WinForms (whereas Dispatcher is for WPF and Silverlight).
  • SharpUrBrain
    SharpUrBrain about 13 years
    @Jon: Can you please share me any article or sample through which I'll get brief idea on Dispatcher(How it works and about its implementation) ?
  • Jon Skeet
    Jon Skeet about 13 years
    @SharpUrBrain: I don't have any particular articles to hand - I'd just be doing a web search for "Dispatcher threading WPF BeginInvoke".
  • SharpUrBrain
    SharpUrBrain about 13 years
    @Jon: So as you suggested in the above answer to use BiginInvoke for Windows Forms apps then is it also same in case of Dispatcher ?
  • Jon Skeet
    Jon Skeet about 13 years
    @SharpUrBrain: Yes, except you need to get hold of the appropriate dispatcher instead of calling BeginInvoke directly on the control.
  • SharpUrBrain
    SharpUrBrain about 13 years
    @Jon: oh OK Many many Thanks Jon, I am still having less knowledge on Dispatcher so let me come up with some basic idea and again if I'll face any Problem then is it OK to disturb you ? :)
  • Jon Skeet
    Jon Skeet about 13 years
    @SharpUrBrain: I would suggest you ask a specific question rather than continuing in comments - and of course check whether the same question has already been asked by someone else first.
  • Rob Parker
    Rob Parker over 12 years
    @AZ: Yes, by "on the UI thread" he means on the particular "UI thread" which owns that particular Control's handle. Typically, there is only one UI thread, but it is possible to have multiple UI threads, and in advanced applications there are reasons why you would want them. Technically, any (normal?) thread could start a UI message pump and become a UI thread--and could later shut down the message pump and no longer be a UI thread. (I assume that's not something to try on a threadpool thread, though.)
  • Ryszard Dżegan
    Ryszard Dżegan over 10 years
    Here is, in addition to the answer, about UI Threading Model (including Control.Invoke and Control.BeginInvoke) with some visualization: stackoverflow.com/a/19023209/2042090
  • Cheung
    Cheung over 10 years
    A very clear and straight forward answer, i always forget the meaning between them, everytimes i return to this post.
  • Thulani Chivandikwa
    Thulani Chivandikwa about 8 years
    Dispatcher invoke and begininvoke will also behave in a manner as control described above.