1

What's the difference between

Application.Current.Dispatcher.Invoke(
    new Action(() =>
    {
        txtRowCount.Text = string.Format("{0}", rowCount);
    })
); //end-Invoke

vs

Application.Current.Dispatcher.Invoke(
    () =>
    {
        txtRowCount.Text = string.Format("{0}", rowCount);
    }
); //end-Invoke

If the compiler complains, i will use the other, but i have no idea what's really going on.

joedotnot
  • 4,810
  • 8
  • 59
  • 91
  • 2
    They are the same. The lambda in the second snippet is implictly cast to an Action. Although usually identical, I'd also recommend to use the TextBlock's Dispatcher, like `txtRowCount.Dispatcher.Invoke(() => txtRowCount.Text = string.Format("{0}", rowCount));` – Clemens Sep 15 '17 at 10:07
  • https://stackoverflow.com/questions/765966/what-is-the-difference-between-new-action-and-a-lambda – mm8 Sep 15 '17 at 10:12

1 Answers1

1

It most likely depends which method you are calling and passing a delegate to. For example, a method with a signature like this could implicitly create an Action using a lambda:

void RunAction(Action thing) {}

Whereas a method like this would not be able to figure out what type of delegate you want:

void RunDelegate(Delegate thing) {}

The reason for this is that the Delegate type is a base class that can represent any delegate expression. For example, you could pass the second function an Action, a Func<T>, a Predicate<T>, an EventHandler or any other delegate you can think of, including custom delegates. The compiler/runtime has no idea what to convert your custom delegate into in this case. It is the responsibility of the function to either figure out how to call the delegate or throw an exception if it does not understand it.

On the other hand, Action is a specific delegate for a method that has no parameters and does not return a value:

delegate void Action();

So, when a method has a parameter typed as Action, then any lambda that has a signature which conforms to that delegate can be implicitly converted for you.


For the Dispatcher.BeginInvoke method, which takes a Delegate, you can pass it any delegate that takes 0 parameters (it is fine if it returns something, but I doubt the return value is used for anything). So, you could pass it something like an Action or a Func<T>. If you pass it a delegate that expects parameters passed to it, it will still compile, but will throw an exception at runtime when the Dispatcher attempts to call the method.

To demonstrate, I made a quick little console app.

static int Main(string[] args)
{
    // These work
    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => Console.WriteLine("Action")));
    Dispatcher.CurrentDispatcher.BeginInvoke(new Func<int>(() => { Console.WriteLine("Func<int>"); return 42; }));

    // This one throws a TargetParameterCountException when the dispatcher gets to it
    //Dispatcher.CurrentDispatcher.BeginInvoke(new Action<bool>(b => Console.WriteLine("Action<bool>")));

    // Queue a dispatcher shutdown at the end and run the dispatcher
    Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => Dispatcher.CurrentDispatcher.InvokeShutdown()));
    Dispatcher.Run();

    Console.WriteLine("Press any key to exit...");
    Console.ReadKey();
    return 0;
}
Xavier
  • 3,254
  • 15
  • 22