You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 04:49:12