Reputation: 340
We know the async
equivalent of Action
is Func<Task>
.
Therefore we could write:
Func<Task> func = async () =>
{
Console.WriteLine(@"waiting ...");
await Task.Delay(300).ConfigureAwait(false);
Console.WriteLine(@"... finished");
};
But it is also possible to write it as an Action
:
Action action = async () =>
{
Console.WriteLine(@"waiting ...");
await Task.Delay(300).ConfigureAwait(false);
Console.WriteLine(@"... finished");
};
This is syntactically correct.
How is it possible to convert Action action
into Func<Task> func
?
Upvotes: 4
Views: 1417
Reputation: 33506
I think that the second snippet is similar to async void
- just anonymous. You really should not use them except for some edge cases like WinForms event handlers..
The compiler manages the returned Task for you and puts it into default thread pool and runs continuations on some selected SynchroContext that is "known to be OK".. I don't remember the rest.. check the gory details of async-void and you will hit articles on why you shouldn't use it except for when absolutely necessary. for example:
Note for example differences in exception handling..
Aah, and I forgot to answer: If that's really async void
then you cannot convert. Simply - the returned Task is gone and you can't obtain it. The Action you've got is something like:
Action action = () =>
{
Func<Task> yourRealTask = async () =>
{
Console.WriteLine(@"waiting ...");
await Task.Delay(300).ConfigureAwait(false);
Console.WriteLine(@"... finished");
};
// ** some compiler-generated code to register/run the task somewhere
// ** so it will be handled properly instea of being lost due to not
// ** returning the Task to the caller
return;
}
so, effectively, the yourRealTask
is not obtainable.. with some luck you may hack it out of some closure via reflection, but.. don't do that. Just use Func<Task>
.
Upvotes: 4
Reputation: 9780
The first case will create a normal Task factory.
The second will create a fire-and-forget async-void method, which is indeed used more rarely.
Since compiler is so neat, it can create both from a single anonymous method, and it's up to the programmer to decide which one he needs.
Upvotes: 1