关闭表单时的StackOverflow

时间:2011-05-25 13:00:40

标签: c# winforms exception stack-overflow

我正在尝试关闭子表单时关闭我的主(父)表单。但是这给了我一个StackOverflow异常。

但是,如果我在FormClosed事件上调用_child.Dispose,它将按预期工作。我应该这样做吗?我为什么要打电话给Dispose? (因为.Show()它不应该是neceserry吗?

一个小型演示:

public partial class frmChild : Form
{
    public frmChild()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        this.Close();
    }
}

public partial class frmParent : Form
{
    private frmChild _child;

    public frmParent()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        _child = new frmChild();
        _child.FormClosed += child_FormClosed;
        _child.Show(this);
    }

    void child_FormClosed(object sender, FormClosedEventArgs e)
    {
        //_child.Dispose(); <-- uncomment and it works
        this.Close(); // <-- StackOverflow exception
    }
}

解决方案,由Teoman Soygul评论(供将来参考):

  

关闭主窗体   this.Close();告诉所有孩子   窗户关闭,以便   创造无限循环

在父母中调用this.Close()后,它会向所有孩子发出关闭aswel的信号,这将发送另一个FormClosed事件...... 我解决了这个问题,没有在_child.Show();中指定所有者我还是没有使用所有者。

1 个答案:

答案 0 :(得分:6)

每次调用this.Close();时,FormClosed事件都会被触发,然后再次调用this.Close();,您将创建一个无限循环。另一方面,如果表单已经处理(如取消注释处置行),则FormClosed事件不会再次触发,因为对象已经被释放。因此,在事件中处理表单是正确的,或者如果您不想这样做,您可以添加一个私有bool字段的额外检查,如:

if (!formClosed)
{
  this.formClosed = true;
  this.Close();
}