避免调用调用控制处置时 [英] Avoid calling Invoke when the control is disposed
问题描述
我有以下的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屋!