从基类覆盖异步 void 事件处理程序方法

3

我不确定如何处理以下情况。有一个定义事件处理方法 '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 方法是可以的,因此无法将其更改为 Task(也不是我的代码)。
那么,我应该如何确保我的派生类在执行自己的代码之前正确地执行 base.OnSomethingHappening()?
这个解决方案在派生类中是否有意义?
public override async void OnSomethingHappening()
        {
           await Task.Run(()=> base.OnSomethingHappening());
            //some more code
        }

我也遇到了同样的问题。@Stephen Cleary,你能帮忙吗? - Irshad
1个回答

6
那么,我应该如何确保我的派生类在执行自己的代码之前正确执行base.OnSomethingHappening()呢?
你没有办法。这就是为什么应避免使用async void方法。它们提供了一种不可能让调用者知道操作何时完成、是否成功完成或者是否存在错误(如果有)。如果您想确保调用者能够获知有关该方法的信息,它需要返回一个Task而不是void。

没错,但是async void不是事件处理程序的一种常见模式吗?无论如何,这并不是我的代码,而是一个非常成熟的框架(Prism)中的内容,我必须应对它... - Bartosz
@Bartosz async void 是一种已经成熟的模式,用于表示一个异步操作,调用者对操作何时完成以及是否成功或失败不感兴趣。事件处理程序是一个常见的情况,其中存在这种情况,但并非所有的事件处理程序都属于此情况,就像并非所有你不关心操作何时结束的情况都是事件处理程序一样。如果你想知道方法何时结束,它需要返回一个 Task,这在 async 方法中是固有的。 - Servy
通常情况下,覆盖事件处理程序或等待其完成是不常见的。通常,事件处理程序将独立运行,互不干扰。 - libertyernie

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接