首页 > 解决方案 > 关闭应用程序时如何避免 ObjectDisposedException

问题描述

我在整个应用程序中都复制了一个问题,但我认为它可以以相同的方式进行管理。

我的 Winforms 应用程序中有一个 IDisposable 类(它是从 System.Windows.Forms.Label 派生的自定义控件)

在那个类中,我有一个计时器,其滴答事件是这样的:

    private void TickTimer(object state)
    {
        Action updateText = () =>
        {
            this.Parent.SuspendLayout();
            this.Text = DateTime.Now.ToString("HH:mm:ss");
            this.Parent.ResumeLayout(false);
        };

        if (this.InvokeRequired)
            this.Invoke(updateText);
        else
            updateText();
    }

另一方面,这是 Dispose 方法:

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            Stop();
            _timer.Dispose();
        }
        base.Dispose(disposing);
    }

问题是在关闭应用程序时,在 this.Invoke(updateText) 调用中抛出异常,告诉主窗体(放置控件的位置)已被释放。

由于这是异步发生的,我该如何管理呢?

我曾考虑在 TickTimer 的每一行中放置一个名为 _isDisposed 的类字段,以检查它是否已被释放,但这真的很难看。

通过在 StackOverflow 中搜索,我找到了一些建议……没有一个奏效。最后的尝试是使用“更新”标志。

    private void TickTimer(object state)
    {
        _updating = true;

        Action updateText = () =>
        {
            this.Parent.SuspendLayout();
            this.Text = DateTime.Now.ToString("HH:mm:ss");
            this.Parent.ResumeLayout(false);

            _updating = false;
        };

        if (this.InvokeRequired)
            this.Invoke(updateText);
        else
            updateText();
    }

在 Dispose 方法中:

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            Stop();
            _timer.Dispose();

            while (_updating) ;
        }
        base.Dispose(disposing);
    }

但是会发生同样的错误。似乎父窗体被放置在子控件之前。

最好的方法是什么?

海梅

标签: c#winformsdisposeobjectdisposedexception

解决方案


推荐阅读