Explicitly use a Func<Task> for asynchronous lambda function when Action overload is available

async-await, c#, c#-5.0, lambda

Solution

Because `Task.Run` has signatures of both `Task.Run(Func<Task>)` and `Task.Run(Action)`, what type is the async anonymous function compiled to? An `async void` or a `Func<Task>`? My gut feeling says it will compile down to an `async void` purely because its a non-generic type however the C# Compiler might be smart and give `Func<Task>` types preference.

The general rule, even without `async`, is that a delegate with a return type is a better match than a delegate without a return type. Another example of this is:

static void Foo(Action a) { }
static void Foo(Func<int> f) { }
static void Bar()
{
  Foo(() => { throw new Exception(); });
}

This is unambiguous and calls the second overload of `Foo`.

Also, is there a way to explicitly declare which overload I wish to use?

A nice way to make this clear is to specify the parameter name. The parameter names for the `Action` and `Func<Task>` overloads are different.

Task.Run(action: async () => {
  await Task.Delay(1000);
});
Task.Run(function: async () => {
  await Task.Delay(1000);
});

Problem

Reading over this blog post on some of the gotchas of C#5's async/await. It mentions in Gotcha #4 something that is quite profound and that I hadn't thought of before. Briefly, it covers the scenario where you have a method that has two overloads, one that takes an `Action` and one that takes a `Func<Task>` (for example `Task.Run`). This issue is rooted in the argument that `async void` methods should only be used for event handlers, with the post then going on to portray the following scenario - What does the compiler infer when a lambda function like the following can be compiled to both a `Func<Task>` and an `Action`: ``` Task.Run(async () => { await Task.Delay(1000); }); ``` Because `Task.Run` has signatures of both `Task.Run(Func<Task>)` and `Task.Run(Action)`, what type is the async anonymous function compiled to? An `async void` or a `Func<Task>`? My gut feeling says it will compile down to an `async void` purely because its a non-generic type however the C# Compiler might be smart and give `Func<Task>` types preference. Also, is there a way to explicitly declare which overload I wish to use? I know I could just create a new instance of `Func<Task>` and pass in the async lambda function there but it would still compile down to a `async void` and then pass that into the constructor of the `Func<Task>`. What is the ideal way to make sure its compiled as a `Func<Task>`?

Original source