我在实践中的观察结果GC.SuppressFinalize
并不总能抑制对终结者的召唤.可能是终结器被调用了.我想知道是否GC.SuppressFinalize
具有请求的性质而不是系统的保证?
更多信息
如果需要,以下信息可能有助于为问题提供更多背景信息.
该GC.SuppressFinalize
文件总结确实状态是一个请求:
请求系统不为指定对象调用终结器.
我想知道这是偶然使用这个词还是真正用于描述运行时行为.
我已经SingletonScope
从Schnell项目中看到了以下课程,该课程基于Ian Griffiths的一个原创想法,除了它更为一般化.我们的想法是在调试版本中检测Dispose
方法是否被调用.如果没有,终结者将最终开始,并且可以发出警告.如果Dispose
被调用GC.SuppressFinalize
则应防止终结器被触发.不幸的是,警告似乎无论如何都会发生,但不是以确定的方式.也就是说,他们不会在每次奔跑中开火.
#region License, Terms and Author(s) // // Schnell - Wiki widgets // Copyright (c) 2007 Atif Aziz. All rights reserved. // // Author(s): // Atif Aziz, http://www.raboof.com // // This library is free software; you can redistribute it and/or modify it // under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation; either version 2.1 of the License, or (at // your option) any later version. // // This library is distributed in the hope that it will be useful, but WITHOUT // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public // License for more details. // // You should have received a copy of the GNU Lesser General Public License // along with this library; if not, write to the Free Software Foundation, // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // #endregion namespace WikiPad { #region Imports using System; using System.Diagnostics; #endregion // // NOTE: To use SingletonScope and ISingletonScopeHelper with value // types, use Nullable. For example, if the type of value to scope // is ThreadPriority then use ISingletonScopeHelper // and SingletonScope . // // // In debug builds, this type is defined as a class so a finalizer // can be used to detect an undisposed scope. // /// /// Designed to change a singleton and scope that change. After exiting /// the scope, the singleton is restored to its value prior to entering /// the scope. /// #if !DEBUG internal struct SingletonScope#else internal sealed class SingletonScope #endif : IDisposable where H : ISingletonScopeHelper , new() { private T _old; public SingletonScope(T temp) { _old = Helper.Install(temp); } private static H Helper { get { return new H(); } } public void Dispose() { // // First, transfer fields to stack then nuke the fields. // var old = _old; _old = default(T); // // Shazam! Restore the old value. // Helper.Restore(old); #if DEBUG GC.SuppressFinalize(this); // Only when defined as a class! #endif } #if DEBUG // // This finalizer is used to detect an undisposed scope. This will // only indicate that the scope was not disposed but (unfortunately) // not which one and where since GC will probably collect much later // than it should have been disposed. // ~SingletonScope() { Debug.Fail("Scope for " + typeof(T).FullName + " not disposed!"); } #endif } }
http://gist.github.com/102424上有一个完整的工作示例,其中包含编译说明,但请注意到目前为止无法确定地再现问题.