c# - 从异步 lambda Action 转换为 Func<Task>?

标签 c# asynchronous lambda

我们知道 async相当于ActionFunc<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/

相关文章:

c# - 如何在 Quartz.NET c# 中获取所有计划作业和触发器的详细信息

c# - 如何等待来自不同线程的异步 UI 方法?

c# - Lambda 表达式类型推断在继承链中是不同的。为什么?

c# - 如何提供要在函数中使用的字段?

c# - global.asax 中的 Application_Error 真的是处理错误的方法吗?

c# - 使用 C# 删除目录上的只读属性

c# - Entity Framework Core 初始迁移时对象已存在

javascript - 在 Internet Explorer 中更改 onchange 处理程序中的 tabindex 时出现奇怪的行为

javascript - Redux Thunk 用于简单的异步请求

c++:将带有参数的lambdas传递给函数