如何在 lambda 方法中传递参数和 async 关键字?

Posted

技术标签:

【中文标题】如何在 lambda 方法中传递参数和 async 关键字?【英文标题】:How pass parameter and async keyword in lambda method? 【发布时间】:2014-03-05 10:57:10 【问题描述】:

如何在这段代码中传递框架元素并使用异步关键字?

SaveImage = new RelayCommand<FrameworkElement>(frameworkElementForPrint =>  

    StorageFile file = await PickImageFileToSave();
    SaveVisualElementToFile(frameworkElementForPrint, file);
);

因为现在 await 不能用了...

【问题讨论】:

假设该类型不是专门为支持async lambdas 而设计的,答案很可能是“你不能”。 (至少不是以一种有意义的方式。你可以让它编译,但它不会按预期工作。) 【参考方案1】:

我建议您将所有逻辑分解为单独的方法,例如:

public async Task SaveImageAsync(FrameworkElement frameworkElementForPrint)

  StorageFile file = await PickImageFileToSaveAsync();
  await SaveVisualElementToFileAsync(frameworkElementForPrint, file);

然后把这个包裹到RelayCommand:

SaveImage = new RelayCommand<FrameworkElement>(async arg =>  await SaveImageAsync(arg); );

这种分离允许您对SaveImageAsync 逻辑进行单元测试(当然假设您使用适当的抽象进行重构)。

This MSDN article 有更多关于async 命令的详细信息。

【讨论】:

这个 lambda 的目的是什么?如果你已经创建了命名方法,为什么不写new RelayCommand&lt;FrameworkElement&gt;(SaveImageAsync) lambda 将async Task 转换为async void。这当然应该避免,但在这种情况下(实现ICommand.Execute),它逻辑上是一个事件处理程序。 我会在一分钟内尝试,但看起来不错。我只是不明白,为什么不在lamba中使用两种方法,而是使用一种命名方法 @Krekkon 两者都可以。 Stephen 建议此更改仅作为最佳实践问题,而不是因为这是一项要求。 我明白了,我的问题只是说说而已:在我原来的例子中,我尝试在 frameworkElementForPrint 之前编写 async ,但编译器让我感到震惊。所以我可以明白为什么在我的例子中可以这样做以及为什么不这样做。 :))

以上是关于如何在 lambda 方法中传递参数和 async 关键字?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Lambda 传递和转换 Comparator 作为方法的参数

将lambda函数作为参数传递,并在方法主体中提供其参数

如何传递和使用任意lambda函数作为参数[重复]

C# 将 Lambda 表达式作为方法参数传递

如何最小起订量委托回调和 lambda 方法

C ++ 11 lambda函数-如何传递参数