【问题标题】:Overriding an async void event handler method from base class从基类覆盖异步 void 事件处理程序方法
【发布时间】:2018-02-13 23:37:12
【问题描述】:

我不确定如何处理以下情况。有一个接口定义了事件处理方法'OnSomethinHappening()'。

有一个基类将其实现为虚拟方法,并在其中使用了一些异步代码。

有一个派生类想重写虚方法,还要调用base.OnSomethingHappening()

 public interface ISomething
    {
        void OnSomethingHappening();
    }

    public class BaseClass
    {
        public virtual async void OnSomethingHappening()
        {
            await Task.Delay(1999);
        }
    }

    public class DerivedClass : BaseClass
    {
        public override void OnSomethingHappening()
        {
            base.OnSomethingHappening();
            //some more code
        }
    }

问题是,我无法将方法调用标记为可等待,因为它返回 void。为事件处理程序提供异步 void 方法很好,因此不能将其更改为任务(这也不是我的代码)。

那么,在去拥有自己的代码之前,我应该如何确保我的派生类正确执行base.OnSomethingHappening()

这个解决方案在派生类中有意义吗?:

public override async void OnSomethingHappening()
        {
           await Task.Run(()=> base.OnSomethingHappening());
            //some more code
        }

【问题讨论】:

  • 我也有同样的问题。 @Stephen Cleary 你能帮忙吗?

标签: c# inheritance async-await


【解决方案1】:

那么,在拥有代码之前,我应该如何确保派生类正确执行 base.OnSomethingHappening()?

你没有。这就是为什么应该避免使用async void 方法的原因。它们无法让调用者知道操作何时完成、是否成功完成或错误是什么(如果有的话)。如果您希望能够确保调用者能够知道有关该方法的信息,则需要返回Task,而不是void

【讨论】:

  • 对,但async void 不是事件处理程序的既定模式吗?无论如何,这不是我的代码,而是一个相当完善的框架(Prism),它有这个,我必须应对它......
  • @Bartosz async void 是一种既定的异步操作模式,在这种模式下,调用者不关心知道操作何时完成,以及它是否成功或为什么不成功。事件处理程序是存在这种情况的常见情况,但并非所有事件处理程序都处于这种情况,就像并非所有您不关心操作何时结束的情况都是事件处理程序一样。如果您想知道方法何时结束,它需要返回一个Task,这只是async 方法所固有的。
  • 覆盖事件处理程序或等待它完成也是不寻常的。通常,事件处理程序将彼此独立运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 2016-09-06
  • 2011-10-05
  • 2015-08-08
  • 1970-01-01
  • 1970-01-01
  • 2015-03-28
相关资源
最近更新 更多