在这种情况下,我的析构函数何时被调用?(C#)

6

在这种情况下,我想知道析构函数何时被调用,如果调用的话,它会在主UI线程上调用吗?

假设我有以下代码,析构函数会在什么时候被调用?它会等到我完成所有函数调用后再被调用吗?

private void Foo()
  {
  MyObject myObj = new MyObject();
  DoSomeFunThingsWithMyObject(myObj);

  myObj = new MyObject(); //is the destructor for the first instance called now?
  DoLongOminousFunctionality(myObj);  
  }
  //Or will it be called after the DoLongOminousFunctionality?

这只是我感兴趣的一个问题,如果在myObj = new MyObject()处中断线程,或者Destructor调用等待线程空闲,会发生什么。

感谢提供信息。

5个回答

17

当垃圾回收器决定清理一些旧对象时,析构函数将被调用。在.NET中,您不能依赖析构函数的执行时间。

相反,如果您想在资源不再需要时清理一些资源(特别是当您拥有任何未受管理的资源,如TCP连接、SQL连接等),则应使用Dispose()。

请参阅实现Dispose方法


3
垃圾回收器执行垃圾回收时,会将带有 finalizer 的对象添加到 finalization 队列中。因此,在对象初始被垃圾回收后,finalizer 可以在任何时间点被调用,而不一定是立即调用。第一句话可能需要进一步澄清。 - Tim Greaves
(给 Fowler 传话)实现 Dispose 的第一条规则:“不要实现 Dispose”。;-) 确保阅读此答案中的链接。选择实现 Dispose 是非常复杂的。垃圾回收意味着在大多数情况下,我们不需要担心对象何时被销毁。 - TheZenker
有时为了代码简洁性,会忽略这个规则(当你不需要释放资源时不要实现dispose)。您是否看到过开发人员只是为了编写一些使用{new myobject()}语句的代码而使用Dispose()。例如:http://social.msdn.microsoft.com/Forums/en-US/winforms/thread/18b8b65e-03cd-4a4f-9b7e-4e44ea5ac5df。 因此,这段代码对资源没有任何作用,它只是展示该语言特性可以用于不同的目的的技巧。 - Bogdan_Ch
这里有另一个规则 - “坚决反对使用Finalize方法!” :) http://www.developer.com/net/csharp/article.php/2233111。然而,关于什么更好的讨论可以在另一个SO主题中找到https://dev59.com/83RB5IYBdhLWcg3wEDul - Bogdan_Ch

3
如果您需要管理对象的生命周期,可以继承自IDisposable接口,并使用using关键字。具体用法请参考这里

2

析构函数或者叫做终结器会在你的实例可以被垃圾回收时某个时间点被调用。与C++中确定性的时间点不同,这个时间点不是确定的。


2

析构函数(或者有些人更喜欢称之为终结器)在一个完全独立的线程上运行。它们没有特定的运行时间。在您的应用程序生命周期结束之前,它们不能保证会被执行,即使在这种情况下,它们也可能不会被调用。


1

析构函数(finalizer)将在垃圾回收器确定您的对象不再使用时调用。Finalizers 在 finalizer 线程上运行,与您的主程序并发运行!

通过正确的优化(JIT 编译器可以轻松消除局部变量),这可能会尽早地发生在第一个 DoSomeFunThingsWithMyObject 调用内部(一旦该方法不再需要其参数),或者在任何以后的时间。也许直到您的程序关闭时才会调用它(在极少数情况下,finalizer 从未被调用)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接