我想等待
一个button.click()
事件。为此创建了一个扩展 GetAwaiter()
方法:
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/)
这样我就可以直接使用 await Button1;
等待 Button1.Click()
事件,这很棒。
但是我不知道如何将这个可等待与诸如 await Task.WhenAny() 之类的东西结合起来
我试过了
await Task.WhenAny(Button1, Button2);
它会告诉我它“无法从按钮转换为任务”。
我想我在这里找到了解决方案: Using `Task.WhenAll` with `INotifyCompletion`只需添加一个方法
public static async Task GetTask()
{
await this;
}
到我的 ButtonAwaiterExtensions 类,但关键字 this
不能在我的静态类中使用。
我不知道该方法要返回什么,也不知道如何等待
任何Button.Click()
。有什么想法吗?
最佳答案
感谢 Sebastian Schumann 评论 ( 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();
}
}
关于c# - 如何将await.WhenAny() 与GetAwaiter 扩展方法结合起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73959407/