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

本文关键字:应用程序 堆栈 栈溢出 表单 | 更新日期: 2023-09-27 17:53:07

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

显示形式:

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),这可能是这种行为的原因吗?

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

您可能是递归调用的受害者。当抛出异常时,查看堆栈跟踪,您将看到哪些方法被重复调用。可能Quit中的一个动作正在触发再次调用Quit的事件。

参见维基百科的递归。


UPDATE(回复你的评论)

我将添加一个标志,告诉对象是否被处置。

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);
    }
}

但是试着理解为什么它被称为递归。

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

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