c# - WinForms 事件在异步等待中乱序执行
问题描述
WinForms 事件出现故障。我想我明白为什么,但我很好奇解决它的最佳方法。
在下面的(人为的)代码中,首先被调用,但是当达到然后被调用Load
时它放弃了控制。一旦完成,终于可以完成。await
Shown
Shown
Load
private async void SomeForm_Load(object sender, EventArgs e)
{
someLabel.Text = "Start Load";
await SomeMethod();
someLabel.Text = "Finish Load";
}
private void SomeForm_Shown(object sender, EventArgs e)
{
someLabel.Text = "Shown";
}
private async Task SomeMethod()
{
await Task.Delay(1).ConfigureAwait(false);
}
我需要确保在执行Load
之前完成Shown
。
这是我目前的解决方案:
Task _isLoadedTask;
private async void SomeForm_Load(object sender, EventArgs e)
{
var tcs = new TaskCompletionSource();
_isLoadedTask = tcs.Task;
someLabel.Text = "Start Load";
await SomeMethod();
someLabel.Text = "Finish Load";
tcs.TrySetResult();
}
private async void SomeForm_Shown(object sender, EventArgs e)
{
await _isLoadedTask;
someLabel.Text = "Shown";
}
明显的缺点是我必须手动设置边界/依赖项。确保事件按顺序执行的最佳方法是什么?
解决方案
在这种情况下,覆盖OnLoad
或订阅Load
具有相同的效果。
但是,订阅Load
会导致委托实例化和调用以及覆盖OnLoad
不会也将更多地控制将要执行的内容和顺序。
尝试这个:
private Task isLoadedTask;
protected override void OnLoad(EventArgs e)
{
this.isLoadedTask = OnLoadAsync();
base.OnLoad(e);
}
private async Task LoadAsync()
{
someLabel.Text = "Start Load";
await SomeMethod();
someLabel.Text = "Finish Load";
}
protected override async void OnShown(EventArgs e)
{
base.OnShown(e);
await _isLoadedTask;
someLabel.Text = "Shown";
}
推荐阅读
- sql - ORACLE SQL COUNT QUERY - 将列添加到报告中以汇总 site_code 出现的次数
- python - ndarray上的numpy除法
- arduino - 如何发送带有事件的串行数据?
- ruby - DATA.each_line - 不返回 header_names
- cassandra - 如何使用 RF1 在多 DC 中实现复制
- python - 如何使用 dateparser 解析 1000 年前的日期?
- bitbucket - TeamCity 提交状态发布者与 BitBucket 两因素身份验证
- android - 有什么方法可以检测拨出电话的状态吗?
- c# - 在 C# 中替换结构
- node.js - 如何在前端scala play框架应用程序的后端使用Node.js?