Are .net finalizers always executed?

风流意气都作罢 提交于 2019-11-26 11:10:02

问题


Are finalizers guaranteed to be executed in .NET at some point (spare power outages and the like)? I know how GC works and that it is nondeterministic when exactly they\'ll run.

(The search did not display good answers, so I\'m adding this question in high expectation of a merge with the not-so-easy-to-discover actual answers. Apart from that, I already know the answer and am going to add it after a few days in case nobody mentioned it.)


回答1:


Finalizers may actually be never executed, as Raymond Chen explains. Kind of funny that this question is asked during his annual CLR week, just two days after he explained it :)

For the lazy ones, the (or rather, one) conclusion is:

A correctly-written program cannot assume that finalizers will ever run.

If you are wondering whether you can rely on finalizers, this is already everything you have to know: Don't rely on finalizers.

As Raymond Chen also states in the linked article:

Finalizers are a safety net, not a primary means for resource reclamation.

If you're looking for how to release resources, have a look at the Disposable pattern.


A finalizer may not run, for example, if:

  • Another finalizer throws an exception.
  • Another finalizer takes more than 2 seconds.
  • All finalizers together take more than 40 seconds.
  • An AppDomain crashes or is unloaded (though you can circumvent this with a critical finalizer (CriticalFinalizerObject, SafeHandle or something like that)
  • No garbage collection occurs
  • The process crashes

(Note: The time values may have changed over time, but were certainly true some time ago.)

I guess there are a lot more things that can cause finalizers to never run. The bottom line is, other than the quote from Mr. Chen, that finalizers are a safety net that decrease the impact of bugs, because for example resources are released sometime, which is better than never, if you forget to do it explicity.




回答2:


If a finalizer throws an exception, other finalizers will not execute.

You can also suppress finalizers if you call SuppressFinalizer on the object.

From MSDN (Object.Finalize):

The Finalize method might not run to completion or might not run at all in the following exceptional circumstances:

  • Another finalizer blocks indefinitely (goes into an infinite loop, tries to obtain a lock it can never obtain and so on). Because the runtime attempts to run finalizers to completion, other finalizers might not be called if a finalizer blocks indefinitely.
  • The process terminates without giving the runtime a chance to clean up. In this case, the runtime's first notification of process termination is a DLL_PROCESS_DETACH notification.


来源:https://stackoverflow.com/questions/3458177/are-net-finalizers-always-executed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!