我的工作线程中有以下代码(以下ImageListView源自Control):

if (mImageListView != null &&
    mImageListView.IsHandleCreated &&
    !mImageListView.IsDisposed)
{
    if (mImageListView.InvokeRequired)
        mImageListView.Invoke(
            new RefreshDelegateInternal(mImageListView.RefreshInternal));
    else
        mImageListView.RefreshInternal();
}

但是,有时我可以通过上面的ObjectDisposedException方法得到一个Invoke。似乎可以在我检查IsDisposed和调用Invoke的时间之间放置该控件。我该如何避免呢?

最佳答案

您的代码中存在隐式竞争条件。可以将控件放置在IsDisposed测试和InvokeRequired测试之间。 InvokeRequired和Invoke()之间还有另一个。如果不确保控件的生命周期超过线程的生命周期,就无法解决此问题。鉴于您的线程正在为列表 View 生成数据,因此应该在列表 View 消失之前停止运行。

为此,可以在FormClosing事件中设置e.Cancel并通过ManualResetEvent通知线程停止。线程完成后,再次调用Form.Close()。使用BackgroundWorker可以轻松实现线程完成逻辑,可以在this post中找到示例代码。

关于c# - 处置控件时避免调用Invoke,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1874728/

10-13 08:02