我在實踐中觀察到GC.SuppressFinalize
並不總是禁止對終結器的調用。可能是終結者被稱爲無關緊要的。因此我想知道GC.SuppressFinalize
是否具有要求而不是保證的性質?GC.SuppressFinalize是否有保證?
更多信息
以下信息可能幫助,如果需要的quesiton提供更多的上下文。
的GC.SuppressFinalize
文檔概要做狀態是請求:
請求,該系統不調用 終結爲指定的對象。
我不知道這是一個偶然使用的單詞還是真正用於描述運行時行爲。
我注意到了這一點,其中SingletonScope
類別取自Schnell項目,該項目基於original idea by 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<T>. For example, if the type of value to scope
// is ThreadPriority then use ISingletonScopeHelper<ThreadPriority?>
// and SingletonScope<ThreadPriority?>.
//
//
// In debug builds, this type is defined as a class so a finalizer
// can be used to detect an undisposed scope.
//
/// <summary>
/// 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.
/// </summary>
#if !DEBUG
internal struct SingletonScope<T, H>
#else
internal sealed class SingletonScope<T, H>
#endif
: IDisposable
where H : ISingletonScopeHelper<T>, 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用匯編指令,但請注意,這個問題不能被確定性至今轉載。
在Dispose方法中沒有Trace,我推測你確定它在finalizer之前被成功調用? – Groo 2009-04-27 08:43:46
@格羅:是的,我確定除非在C#中使用。 :) – 2009-04-27 11:46:00