我们知道 async
相当于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
进入Func<Task> func
?
最佳答案
我认为第二个片段类似于 async void
- 只是匿名。你真的不应该使用它们,除了一些边缘情况,比如 WinForms 事件处理程序..
编译器为您管理返回的 Task 并将其放入默认线程池,并在某些“已知正常”的选定 SynchroContext 上运行延续。我不记得其余的了。检查异步的详细信息-void 并且你会看到关于为什么你不应该使用它的文章,除非绝对必要。例如:
注意例如异常处理的差异..
啊,我忘了回答:如果那真的是 async void
那么你不能转换。很简单 - 返回的 Task 已经消失,你无法获得它。你得到的 Action 是这样的:
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>
.
关于c# - 从异步 lambda Action 转换为 Func<Task>?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45057701/