关闭打开表单的应用程序时堆栈溢出

时间:2014-03-25 20:10:08

标签: c# winforms stack-overflow

当我创建并显示表单并在表单仍处于打开状态时关闭(终止)应用程序时,会抛出堆栈溢出异常。

显示表格:

private static void OpenSettings(Object sender, EventArgs e)
{
    ActionLog.Write("Opened Settings");
    form_Settings f_Settings = new form_Settings();
    f_Settings.Show();
}

使用上下文菜单回调关闭我的应用程序:

private static void Quit(Object sender, EventArgs e)
{
    ActionLog.Write("Exit");
    Settings.Serialize();
    Environment.Exit(0);
}

GUI.form_Settings.Dispose函数抛出异常。该函数永远不会退出并导致无限递归。

如果我在关闭应用程序时没有打开窗口,一切都很顺利。

怎么样?

//编辑:

protected override void Dispose(bool disposing)
{
    if (disposing && (components != null))
    {
        components.Dispose();
    }
    base.Dispose(disposing);
}

猜猜这很标准,我找不到任何其他定义。另外我想提一下我正在使用自定义框架(https://github.com/viperneo/winforms-modernui),这可能是造成这种行为的原因吗?

2 个答案:

答案 0 :(得分:1)

可能你是递归电话的受害者。抛出异常时查看堆栈跟踪,您将看到重复调用哪些方法。可能Quit中的一项操作是触发再次调用Quit的事件。

请参阅维基百科上的Recursion


更新(以回应您的评论)

我会添加一个标志,告诉对象是否已被丢弃。

private bool _disposed = false;

protected override void Dispose(bool disposing)
{
    if (!_disposed) {
        _disposed = true;

        if (disposing && (components != null))
        {
            components.Dispose();
            components = null; // Now they cannot be disposed again.
        }

        base.Dispose(disposing);
    }
}

但是试着理解为什么它被递归调用。其他地方可能还隐藏着另一个错误。

答案 1 :(得分:0)

我刚发现自定义框架(https://github.com/viperneo/winforms-modernui)没有按预期工作。使用常规Windows窗体一切正常,不会抛出任何异常。但由于某些原因,在使用框架时,如果在应用程序退出之前未处理表单,则抛出异常。希望有人在考虑使用此框架时可以阅读此内容。

感谢Hans Passant关于自定义框架的提示!