我们知道async
的{{1}}等效于Action
。
因此我们可以写:
Func<Task>
但也可以将其写为Func<Task> func = async () =>
{
Console.WriteLine(@"waiting ...");
await Task.Delay(300).ConfigureAwait(false);
Console.WriteLine(@"... finished");
};
:
Action
这在语法上是正确的。
如何将Action action = async () =>
{
Console.WriteLine(@"waiting ...");
await Task.Delay(300).ConfigureAwait(false);
Console.WriteLine(@"... finished");
};
转换为Action action
?
答案 0 :(得分:4)
我认为第二个代码段与async void
类似 - 只是匿名。除了WinForms事件处理程序之类的边缘情况之外,你真的不应该使用它们。
编译器为您管理返回的Task并将其放入默认线程池并在某些选定的“已知正常”的SynchroContext上运行continuation ..我不记得其余的..检查异步的血腥细节-void你会发表关于为什么你不应该使用它的文章,除非绝对必要。例如:
请注意异常处理中的示例差异。
Aah,我忘了回答:如果那真的是async void
那么你就无法转换。简单地说 - 返回的任务已经消失,你无法获得它。你得到的行动是这样的:
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;
}
所以,实际上,yourRealTask
是无法获得的......运气好的话,你可能会通过反射来解决它的问题,但是......不要这样做。只需使用Func<Task>
。
答案 1 :(得分:1)
第一种情况将创建一个正常的任务工厂。
第二个将创建一个即发即弃的async-void方法,确实很少使用它。
由于编译器非常简洁,它可以通过单个匿名方法创建,并且由程序员决定他需要哪一个。