2011-03-21 98 views
0

让我们假设我在一个表单中创建一个后台工作器作为一个组件。然后启动它。 现在,如果我关闭表单,那么BackgroundWorker将仍然在运行。 您会解释一下,表单已关闭,表单对象内创建的所有资源都已关闭,但BackgroundWorker仍在运行。这是什么原因?这是因为它是在不同的线程上运行。 当它的资源将被CLR重新获得。c中的BackgroundWorker和资源管理器#

+0

这是你在你的机器上观察到的,还是你问如果后台工作人员将运行? – gideon 2011-03-21 11:16:31

+0

取决于谁在听背景工作者的事件? – 2011-03-21 11:16:35

+0

我正在观察我的机器,在关闭表单后,backgroundworker仍在运行。 – 2011-03-21 11:18:22

回答

1

的背景工人为默认情况下不连接到形式或线程它在创建。

甲背景工人是像任何其他对象的对象。当没有更多的活动引用时它会被收集。

所以它真的取决于对象创建的方式和位置,以及大多数 - 谁仍然有对它的引用。

人们往往忘记的是事件也是参考。因此,如果有另一个对象正在监听工作人员的事件,工作人员仍将被引用,因此不会被收集。

注:

Form.Close()从视线中删除的对话框,并调用关闭()和()关闭方法。您仍然可以访问该表单并稍后恢复。

Form.Dispose()销毁对话框并将其资源释放回操作系统。它不调用窗体的Closing()和Closed()方法。一旦处置,你可能不记得一个表格。 Dispose()也将调用所有Form的组件的Dispose()方法。

+0

它实际上是连接到窗体,如果他从工具箱中将它放到窗体上。它位于其组件集合中,它被放置在Form.Dispose上。 – 2011-03-21 11:26:50

+0

然后它与谁连接。当我在窗体设计器类中看到它(工作者)引用。 – 2011-03-21 11:30:25

+0

再次,取决于实施。如果它在表单的组件中,则对表单的Dispose()调用将调用其中所有组件的dispose()。但一个窗体Close()不会处理()... Dispose()和Close()之间有很大的区别 – 2011-03-21 11:35:53

1

除非您故意压制处置,否则后台工作人员将与表单一起处理。如果是这种情况,那么它应该在不确定的时间收集垃圾。我说应该是因为事情可能会引用后台工作者。至于线程,我相信它会在dispose中清理,应该在关闭时从窗体中调用它。

如果表单是主表单,并且关闭导致主要前景线程关闭,则所有后台线程都将关闭/死亡。

+0

+1 jeez正是我输入的内容! =) – gideon 2011-03-21 11:17:53

0

当您关闭表单并处理它时,BackgroundWorker也会处理,但它不会停止线程运行。所以只有在DoWork完成后才能完全销毁。

您可以通过取消关闭表单并在后台工作人员上调用CancelAsync来表明您希望完成表单来解决此问题。等到它完成后,只有在这之后,您才能真正关闭表单。