gpt4 book ai didi

c# - 当 ThreadPool WaitCallback 在关闭后调用 Form 时,Form 会发生什么情况?

转载 作者:行者123 更新时间:2023-11-30 14:00:54 27 4
gpt4 key购买 nike

假设在 Windows 窗体中,我启动了一个长时间运行的任务,如下所示:

ThreadPool.QueueUserWorkItem(new WaitCallback(UpdateDailyTasksChart));

然后,这个函数运行了一段时间,但我在它完成之前关闭了窗口。

private void UpdateDailyTasksChart (object param)
{
//Call Data Access Layer, go get MySQL Data. But I close the Form.
UICallback(chartData); //The Form is closed when this is executed.
}

现在这是 UICallback 的作用:

private delegate void UICallbackDel(object chartData);
private void UICallback (object chartData)
{
if (InvokeRequired)
{
this.Invoke(new UICallbackDel(UICallback), chartData);
}
else
{
aButtonOnMyForm.Visible = false; //But the Form has been closed!
}
}

奇怪的是,这段代码并没有崩溃。

我在 Form_Closed 事件中放置了断点,它确实执行了。我没有检查表单是否仍然存在,例如,用类变量声明它。但我猜是这样。

所以问题是:GC 只会在我的线程结束时收集 Form?或者它会发生什么?

最佳答案

这里有两点:

  1. 如果您显式处理表单,您可能希望在工作项委托(delegate)执行时引发 ObjectDisposedException
  2. 您的工作项委托(delegate)通过 thisInvokeRequired(反过来引用 this)和 aButtonOnMyForm 持有对表单的引用。因此,只要 ThreadPool 线程尚未完成执行,您的表单就没有资格进行垃圾回收。这就是代码不会崩溃的原因。 (注意:无论如何,this 始终是隐式可访问的。)

由此得出的另一件事是,通常明智的做法是在表单关闭之前从表单中注销外部事件处理程序,以免造成内存泄漏。如果你注册了一个 lambda 表达式或匿名委托(delegate),你需要保存对它的引用以便稍后注销。简单地复制和粘贴相同的代码是行不通的。

关于c# - 当 ThreadPool WaitCallback 在关闭后调用 Form 时,Form 会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9557036/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com