【发布时间】:2021-05-17 20:58:06
【问题描述】:
我会尽量简短。两种形式:
Form1 (button1, textBox1)
public partial class Form1 : Form
{
private readonly Form2 fr2 = new Form2();
public Form1()
{
InitializeComponent();
fr2.textBox1 = textBox1;
}
private async void button1_Click(object sender, EventArgs e)
{
textBox1.Text = string.Empty;
if (fr2.ShowDialog() == DialogResult.OK)
textBox1.AppendText("Form1" + Environment.NewLine);
}
}
Form2(带有 button1.DialogResult == DialogResult.OK 的 button1)
public partial class Form2 : Form
{
public TextBox textBox1;
public Form2()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
textBox1.AppendText("Form2 A" + Environment.NewLine);
await Task.Delay(1000);
textBox1.AppendText("Form2 B" + Environment.NewLine);
Hide();
}
}
- 运行
- 点击Form1.Button1
- 点击Form2.Button1
为什么是 Textbox.Text ==
@"Form2 A
Form1
Form2 B
";
而不是
@"Form2 A
Form2 B
Form1
"?
为什么表单甚至没有完成事件处理程序就“返回”给调用者并稍后完成?
这是记录在案的行为还是错误?
更新:
显然,如果 button.DialogResult 是预设的,原始 winform 的表单事件处理代码未更新以考虑异步事件处理程序,它只是被视为“触发并忘记”异步方法调用。我必须研究更多,看看如果抛出异常会发生什么。似乎异步机器也被“解雇并忘记了”(没有Task 保存以供以后使用)?!这是与串行案例非常不同的行为,并且在任何地方都没有记录。现场评论await,Hans Passant!
【问题讨论】:
-
我假设 Form1 中的代码应该添加“Form1 A”而不仅仅是“Form1”?
-
因为await这个关键字引发了一百万个bug。将按钮的 DialogResult 属性设置回 None,这样您的代码就可以控制对话框的生命周期。不要使用 Hide(),取消对话框,使用 this.DialogResult = DialogResult.OK;
-
@JackT.Spades 是的。你说的对。剪切、粘贴和编辑不是避免错误的好方法;-) 已修复
标签: c# winforms asynchronous async-await