如何将await.WhenAny() 与GetAwaiter 扩展方法结合起来

2024-04-16

我想要await a button.click()事件。为此创建了一个扩展GetAwaiter() method:

public static class ButtonAwaiterExtensions
{
    public static ButtonAwaiter GetAwaiter(this Button button)
    {
        return new ButtonAwaiter()
        {
            Button = button
        };
    }

    public class ButtonAwaiter : INotifyCompletion
    {
        public bool IsCompleted
        {
            get { return false; }
        }

        public void GetResult()
        {

        }

        public Button? Button { get; set; }

        public void OnCompleted(Action continuation)
        {
            RoutedEventHandler? h = null;
            h = (o, e) =>
            {
                Button!.Click -= h;
                continuation();
            };
            Button!.Click += h;
        }

    }
}

(我在这里找到的:http://blog.roboblob.com/2014/10/23/awaiting-for-that-button-click/ http://blog.roboblob.com/2014/10/23/awaiting-for-that-button-click/)

这样我就可以等待Button1.Click()事件直接与await Button1;这太棒了。

但我不知道如何将这个等待与类似的东西结合起来 await Task.WhenAny()

I tried

等待 Task.WhenAny(Button1, Button2);

它会告诉我它“无法从按钮转换为任务”。

我想我在这里找到了解决方案:将“Task.WhenAll”与“INotifyCompletion”结合使用 https://stackoverflow.com/questions/64554979/using-task-whenall-with-inotifycompletion只需添加一个方法

public static async Task GetTask()
{
    await this;
}

到我的 ButtonAwaiterExtensions 类,但是关键字this不能在我的静态类中使用。

我不知道该方法要返回什么,或者一般如何返回await any Button.Click()。有任何想法吗?


感谢塞巴斯蒂安·舒曼的评论(如何将await.WhenAny() 与GetAwaiter 扩展方法结合起来 https://stackoverflow.com/questions/73959407/how-can-i-combine-await-whenany-with-getawaiter-extension-method)我通过直接向 ButtonAwaiterExtensions 类添加另一个扩展方法解决了我的问题:

public async static Task AsTask(this Button self) => await self;

完整的解决方案:

public static class ButtonAwaiterExtensions
{
    public static ButtonAwaiter GetAwaiter(this Button button)
    {
        return new ButtonAwaiter()
        {
            Button = button
        };
    }

    public class ButtonAwaiter : INotifyCompletion
    {
        public bool IsCompleted
        {
            get { return false; }
        }

        public void GetResult()
        {

        }

        public Button? Button { get; set; }

        public void OnCompleted(Action continuation)
        {
            RoutedEventHandler? h = null;
            h = (o, e) =>
            {
                Button!.Click -= h;
                continuation();
            };
            Button!.Click += h;
        }
    }
   public async static Task AsTask(this Button self) => await self;
}

替代(短一点)实现GetAwaiter可能:

public static TaskAwaiter GetAwaiter(this Button self)
{
    ArgumentNullException.ThrowIfNull(self);
    TaskCompletionSource tcs = new();
    self.Click += OnClick;
    return tcs.Task.GetAwaiter();

    void OnClick(object sender, EventArgs args)
    {
        self.Click -= OnClick;
        tcs.SetResult();
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将await.WhenAny() 与GetAwaiter 扩展方法结合起来 的相关文章

随机推荐