关闭应用程序时如何避免ObjectDisposedException

时间:2019-01-18 16:27:47

标签: c# winforms dispose 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);
    }

问题是关闭应用程序时,此.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);
    }

但是发生相同的错误。似乎父级表单已放置在子级控件之前。

最好的方法是什么?

Jaime

0 个答案:

没有答案