【发布时间】:2022-04-01 00:20:18
【问题描述】:
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 事件?
-
我没有。我将如何使用
OnLoad解决它? -
我很确定你不能。唯一真正的选择是将该代码移出“SomeForm”的创建者,让他们在调用
.Show...之前触发/等待异步部分(评论因为我有一段时间没有接触过WinForms,也许现在有一些异步支持) -
这个问题有用吗? Task sequencing and re-entracy
-
这是一场你无法获胜的线程竞赛,ConfigureAwait() 调用使情况变得更糟。该代码看起来太假了,无法提出解决方法,但请考虑根本不使用事件。创建一个调用表单构造函数的异步方法,执行异步舞蹈,然后调用 Show() 结束。
标签: c# winforms async-await