在处理控件时避免调用Invoke

Ozg*_*tak 27 c# controls dispose invoke

我的工作线程中有以下代码(ImageListView下面是派生自的Control):

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

但是,我ObjectDisposedException有时会得到Invoke上面的方法.似乎控制可以在我检查IsDisposed和呼叫之间处理Invoke.我怎么能避免这种情况?

Isa*_*avo 19

你在这里有一个竞争条件.你最好只是捕获ObjectDisposed异常并完成它.事实上,我认为在这种情况下,它是唯一可行的解决方案.

try
{
    if (mImageListView.InvokeRequired)
       mImageListView.Invoke(new YourDelegate(thisMethod));
    else
       mImageListView.RefreshInternal();
} 
catch (ObjectDisposedException ex)
{
    // Do something clever
}
Run Code Online (Sandbox Code Playgroud)


Han*_*ant 14

您的代码中存在隐式竞争条件.控件可以在IsDisposed测试和InvokeRequired测试之间进行处理.InvokeRequired和Invoke()之间还有另一个.如果不确保控件的使用寿命超过线程的寿命,则无法解决此问题.鉴于您的线程正在为列表视图生成数据,它应该在列表视图消失之前停止运行.

通过在FormClosing事件中设置e.Cancel并通过ManualResetEvent发出停止信号来执行此操作.线程完成后,再次调用Form.Close().使用BackgroundWorker可以轻松实现线程完成逻辑,在本文中查找示例代码.

  • 你能保证它只会是一个ObjectDisposedException吗?如果它是一个合法的ObjectDisposedException怎么办?这是一个兔子洞.解决问题,不要射击信使. (2认同)

归档时间:

查看次数:

19800 次

最近记录:

7 年,5 月 前