如何确定C#控件是否正在卸载?

如何确定C#控件是否正在卸载?,c#,timer,user-controls,C#,Timer,User Controls,在我的C#Windows窗体应用程序中,我有一个用户控件,它包含其他控件并执行自己的逻辑。其中之一是延迟调用(计时器调用),在用户完成键盘输入(实时过滤文本)后执行某些操作。它为此访问其他控件,其中一个是文本输入控件。此方法在上次输入事件发生500毫秒后调用 现在,当应用程序终止时延迟的调用正在运行时,我遇到了一个问题。当我输入一些文本,然后等待大约500毫秒(似乎每次都有效),然后按Alt+F4关闭窗口时,应用程序在尝试访问文本输入控件时抛出NullReferenceException。当我在

在我的C#Windows窗体应用程序中,我有一个用户控件,它包含其他控件并执行自己的逻辑。其中之一是延迟调用(计时器调用),在用户完成键盘输入(实时过滤文本)后执行某些操作。它为此访问其他控件,其中一个是文本输入控件。此方法在上次输入事件发生500毫秒后调用

现在,当应用程序终止时延迟的调用正在运行时,我遇到了一个问题。当我输入一些文本,然后等待大约500毫秒(似乎每次都有效),然后按Alt+F4关闭窗口时,应用程序在尝试访问文本输入控件时抛出NullReferenceException。当我在最后一次输入后立即关闭窗口或在最后一次输入后一秒或更长时间关闭窗口时,不会发生这种情况

似乎正在处理控件或其他内容,其方法无法再访问子控件。因此,当控件处于该状态时(无论是谁,也不管该状态是什么),需要首先停止这些计时器,以便可以安全地处理控件

我已经尝试在OnHandleDestroyed方法(重写)和设计器生成的Dispose方法开始时停止计时器。没有任何帮助


在调用base.OnFormClosed()之前,当停止重写的OnFormClosed方法中的计时器时,此过程在常规形式中工作正常。我只是在用户控件中找不到合适的事件。

在用户控件中尝试以下操作:

bool isDisposed;
protected override void Dispose(bool disposeManaged)
{
    if(!isDisposed)
    {
        if(disposeManaged)
        {
            //Dispose your timer here
        }
        isDisposed = true;
    }
}
另一种可能性是,您的某个UI类不进行清理。它为一个事件注册自己,但在手动处理时不会取消注册。GC从不收集它,当下次触发该事件时,它会尝试访问在之前的
Dispose(…)
调用期间设置为null的一些成员


另一种可能是,代码中有一个更复杂的竞争条件,但从这里很难说。

这就是我对Dispose方法的意思。我在该方法的开头添加了计时器取消代码,这样它肯定会被执行。但是它没有帮助。您确定
UserControl
的父级调用了它的
Dispose
?链必须从某个地方开始,通常是表单,但检查它不会有任何伤害。没错,它会被调用。首先是父控件(窗体),然后是控件本身。但是我的计时器似乎已经在队列中,所以取消计时器在这里没有任何效果。我现在发现的另一个解决方案是在计时器调用的方法中直接使用
IsDisposed
属性。当调用
Dispose
时(所有这些都在UI线程中同步发生),IsDisposed总是返回true,然后我就不会对控件执行任何操作了。嗯,这里的格式化是如何工作的?这里没有文档,所以你的问题解决了?您想添加自己的答案吗?