避免`Control.Invoke`和析构函数之间的死锁,重新访问UserControl

时间:2012-05-16 20:12:56

标签: .net winforms deadlock invoke dispose

我遇到了有关here问题的变体。我没有扩展System.Windows.Form的类,而是有一个扩展System.Windows.UserControl的类,它没有FormClosing个事件。

我考虑过向用户控件添加Close方法,我告诉本机线程停止。当它停止时,它会向用户控件发出一个事件,该控件会自动调用Dispose。这种方法的问题是从对象调用Dispose处理(自杀?)似乎是一种不好的做法,我不得不写一个什么都不做的终结器(以避免双重处理),这感觉更糟糕。

建议?

更新:我的用户控件位于扩展System.Windows.Forms.ToolStripControlHost的类中,该类的实例位于主应用程序表单中。

1 个答案:

答案 0 :(得分:1)

我会向用户控件添加某种方法,并在表单FormClosing事件中调用它...

用户控件中的方法将被阻塞,因此在处理完成之前它不会返回。

但是,您可以取消Closing事件中的结束,禁用表单,在后台执行某些操作,完成后,从代码中关闭表单。例如:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    // if disposed, close as usual
    if (myControl == null || myControl.Disposed) return;
    // disable the form so nothing can be done while
    // were asynchronously disposing the form...
    this.Enabled = false;
    e.Cancel = true;
    var context = TaskScheduler.FromCurrentSynchronizationContext();
    Task.Factory.StartNew(()=>myControl.Dispose())
        .ContinueWith(a=>Close(), context);
}