避免调用调用控制处置时 [英] Avoid calling Invoke when the control is disposed

查看:152
本文介绍了避免调用调用控制处置时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下的code在我的工作线程( ImageListView 下面是控制导出):

I have the following code in my worker thread (ImageListView below is derived from Control):

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

不过,我得到一个的ObjectDisposedException 有时与调用上面的方法。看来,控件可以处理我检查 IsDisposed ,我叫调用之间的时间。我怎样才能避免?

However, I get an ObjectDisposedException sometimes with the Invoke method above. It appears that the control can be disposed between the time I check IsDisposed and I call Invoke. How can I avoid that?

推荐答案

有在code隐含的竞争条件。该控制可以设置你的IsDisposed试验和InvokeRequired测试之间。有InvokeRequired和调用()之间的一个又一个。不保证控制会超越线程的生活,你不能修复这个问题。鉴于你的线程为列表视图生成的数据,它应该停止运行列表视图中消失了。

There are implicit race conditions in your code. The control can be disposed between your IsDisposed test and the InvokeRequired test. There's another one between InvokeRequired and Invoke(). You can't fix this without ensuring the control outlives the life of the thread. Given that your thread is generating data for a list view, it ought to stop running before the list view disappears.

通过在事件的FormClosing设置e.Cancel和信令线程停止使用的ManualResetEvent这样做。当线程完成,()再次调用Form.Close。 Thread.Abort的()是一个遥远的第二选择,但更容易实现。使用的BackgroundWorker可以轻松实现线程完成逻辑。

Do so by setting e.Cancel in the FormClosing event and signaling the thread to stop with a ManualResetEvent. When the thread completes, call Form.Close() again. Thread.Abort() is a distant second choice but much easier to implement. Using BackgroundWorker makes it easy to implement the thread completion logic.

这篇关于避免调用调用控制处置时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆