如何在使用frm.Show()后实现关闭窗体再执行代码?
问题:使用
frm.Show()后,如何实现窗体关闭再执行后续代码? 你提到因为特定需求必须用frm.Show()而非frm.ShowDialog(),但希望达成和ShowDialog()一样的效果——也就是等窗体关闭后再执行后续代码。就像你给出的示例里,Example1的消息框会在Form1关闭后才弹出,而Example2的消息框在Form1刚打开就弹出来了。
先贴出你提供的示例代码:
private void Example1_Click(object sender, EventArgs e) { Form1 frm = new Form1(); frm.ShowDialog(); MessageBox.Show("EXECUTE CODE"); } private void Example2_Click(object sender, EventArgs e) { Form1 frm = new Form1(); frm.Show(); MessageBox.Show("EXECUTE CODE"); }
下面给你两种实用的解决方案:
方法1:订阅窗体的FormClosed事件
这是最直观的实现方式,给Form1绑定一个关闭事件处理逻辑,只有当窗体关闭时才触发后续代码:
private void Example2_Click(object sender, EventArgs e) { Form1 frm = new Form1(); // 绑定FormClosed事件,窗体关闭时执行匿名方法里的代码 frm.FormClosed += (senderForm, eventArgs) => { MessageBox.Show("EXECUTE CODE"); // 记得释放窗体资源,避免内存泄漏 frm.Dispose(); }; frm.Show(); }
这样修改后,只有当Form1被关闭的瞬间,消息框才会弹出来,完全符合你的需求。
方法2:用异步方式模拟ShowDialog()的等待逻辑
如果你更喜欢让代码结构和ShowDialog()保持一致(后续代码写在Show()语句之后),可以用TaskCompletionSource配合异步方法来实现“等待窗体关闭”的效果:
private async void Example2_Click(object sender, EventArgs e) { Form1 frm = new Form1(); var taskCompletionSource = new TaskCompletionSource<bool>(); // 窗体关闭时标记任务完成 frm.FormClosed += (senderForm, eventArgs) => { taskCompletionSource.SetResult(true); frm.Dispose(); }; frm.Show(); // 等待窗体关闭的任务完成,这段代码会暂停到窗体关闭 await taskCompletionSource.Task; // 这里的代码会在窗体关闭后执行 MessageBox.Show("EXECUTE CODE"); }
这种写法让代码逻辑更连贯,看起来和ShowDialog()的流程差不多,但又保留了Show()的非阻塞特性(当然当前事件方法会因为await暂停,直到窗体关闭)。
注意事项
- 如果Form1会被多次创建使用,记得在合适的时机解绑
FormClosed事件,避免内存泄漏; - 第二种方法里,按钮的事件方法必须加上
async修饰符,这是使用await的必要条件。
内容的提问来源于stack exchange,提问作者Dim Chris
相关产品推荐
相关产品推荐

