【问题标题】:Async / Await using delegates使用委托的异步/等待
【发布时间】:2013-12-09 14:17:30
【问题描述】:

我想为事件订阅异步方法。

但是,编译器不会让我。

我该怎么做?

例子:

class SearchBase
{
    public delegate void ReuestingCollectionHandler();
    public event ReuestingCollectionHandler RequestingCollection = null;
}
.
.
.
SearchBase.RequestingCollection += LoadCandidates;


 public async Task LoadCandidates()
 {
    var queryText = string.Empty;
    Candidates = await CandidatesManager.GetCandidates(Profile.Instance.RecruiterId);
 }

【问题讨论】:

  • Jusr 编写一个封装方法,该方法将作为委托函数,并在该方法内部调用异步方法

标签: c# events async-await


【解决方案1】:

您的LoadCandidates 方法是否仅用作事件处理程序(如您发布的代码所示)?

如果是这样,您应该将其更改为async void,而不是返回Task。这是事件处理程序的常用签名,也是可以接受/推荐使用 async void 方法的极少数情况之一。

如果你打算在其他地方使用它并且需要它来返回一个任务,那么围绕它编写一个async void 包装器方法,并使用这个包装器作为事件处理程序。 p>

public async void LoadCandidatesAsync()
 {
    await LoadCandidates();
 }

事件处理程序应该返回任何东西。如果调用者有 100 个客户端监听该事件,他将只获得其中一个处理程序的返回值。 如果调用者想从处理程序中得到一些东西,那么它应该向它们发送一个可变的EventArgs 实例。

这里有一个更完整的解释为什么事件处理程序应该返回voidhttps://stackoverflow.com/a/3325425/857807

【讨论】:

  • 请记住,这样做意味着当您引发事件时,处理程序可能会并行执行,而您不会发现它们何时完成。
  • 我见过很多地方提到async void 对事件处理程序有效。 WPF 或 Win Forms 应用程序中特别提到的一种。所以只是想确认一下,在 ASP.NET 应用程序中也可以吗?例如关闭秒表间隔回调或说出由 CMS 引发的事件?
【解决方案2】:

您的委托需要匹配,您不能将返回 Task 的方法分配给返回类型为 void 的委托。

【讨论】:

  • 但我也不能将“异步任务”应用于委托人的签名。那么我有什么选择呢?
  • 异步是语法糖,可帮助您构建返回任务的方法。您的委托应该是公共委托 Task ReuestingCollectionHandler()。请注意,您不会以标准方式使用事件,因此请确保您不会遇到麻烦。
  • 我喜欢您不考虑将 LoadCandidates 方法更改为 async void,这是您的选择之一。在我看来,您应该尝试使用 Func 或 Action 来做这样的事情。
  • @Zache @fsimonazzi 为什么事件处理程序会返回 void 以外的内容?
  • @ScottChamberlain 问题在于,如果有多个处理程序,您将只能获得其中一项任务,而不是所有任务,除非您有自定义的 event 实现。只等待可能的许多任务中的一个将是一个非常糟糕的主意。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-02
  • 2017-06-23
  • 2018-06-12
  • 1970-01-01
  • 2015-12-05
  • 1970-01-01
相关资源
最近更新 更多