c# - 异步/等待 Lambda

标签 c# asynchronous lambda async-await

我有一个奇怪的问题,结合 async/await 使其工作: 我创建了一个小程序,它应该基本上处理每个操作的 try/catch:

    internal static void HandledAction(Action action, Info infoBar)
    {
        try
        {
            action();
        }
        catch (Exception ex)
        {
            infoBar.SetError("An Exception occured: " + ex.Message);
            WriteLog(ex.StackTrace);
        }

没什么特别的,但它是值得的,因为更改错误处理非常容易。 但是,如果我想在 Lambda 中实现数据异步,会发生什么?让我们举个简单的例子:

    private void mnuImportData_Click(object sender, RoutedEventArgs e)
    {
        ActionHelper.HandledAction(async () =>
        {
            throw new NotImplementedException("Ups");
        }, infoMain);
    }

当然,HandledAction 被调用,通过,因为它取回了指针,并且抛出了异常,当然没有被处理。

我想我必须创建一个 AsyncHandledAction,并将操作设置为异步,但是有没有更简单的方法来解决这个问题?

我想很多人都使用中央异常处理,对此有更好的解决方案吗?

提前致谢

马蒂亚斯

编辑:我创建了一个示例,它应该显示我需要的 netter:我基本上不希望我传递的整个 Action 是可等待的,但是 Lambda 中的一个调用是:

ActionHelper.HandledActionAsync(() =>
        {
            //elided
            CheckFileResult rslt = await excelImport.CheckFilesAsync(tmpPath);
            //elided
        }, infoMain);

当然,通过这样做,我得到了错误:

错误 3 'await' 运算符只能在异步 lambda 表达式中使用。考虑使用“async”修饰符标记此 lambda 表达式。

最佳答案

原因是:Action而不是Func。由于你的:

async () =>
        {
            throw new NotImplementedException("Ups");
        }

事实上是:

async void Method() { }

Func<Task>是:

async Task Method() { }

Async void 将捕获 SynchronizationContext.Current当抛出异常时,它将被发布到 SynchronizationContext通过 SynchronizationContext.Post() -(在 Windows 运行时中,您可以捕获这些类型的异常)。如果是ASP.NET/Console application SynchronizationContext.Current返回 null,这意味着异常将传播到线程池,我不确定,但我认为不可能捕获它。但是当返回时 Task通过异步方法异常可以通过这个返回的任务编码给调用者。还值得一提的是,异步 lambda 表达式总是更喜欢带有 Func<Task> 的方法。在 Action .一般规则是:永远不要使用 async void ( async Action ) 除非它是“顶级方法”(在示例事件处理程序中)。

关于c# - 异步/等待 Lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25647062/

相关文章:

python - Twisted 服务器,从 Twitter 流 api 消费并同时提供静态内容

c# - LINQ/Lambda 等价于 SQL

amazon-web-services - AWS Lambda 和 API 网关阶段

c# - HttpSessionLifecycle对象序列化结构图

c# - 重新启动 Windows 窗体应用程序

c# - 将嵌套在动态对象中的 C# 列表中的第一项和最后一项序列化为 JSON

c# - 如何动态地向匿名对象添加属性?

java - 如何使用 JUnit 测试异步进程

testing - Qunit beforeEach,afterEach - 异步

android - 在 Kotlin 中设置 Android 监听器 - 在 lambda 中使用 return