Ste*_*unn 4 .net garbage-collection
这是很难找到在设计/编译是那些没有正确地放置了IDisposable,但时间类型.在运行时有哪些方法可以找到它们?
IDisposable如果您的类型是资源饥饿,那么实现是一种很好的做法,但是,这只是一种很好的做法,并且不能由编译器强制执行.
有一两件事你可以做,使滥用IDisposableS比显着,是让他们throw或assert在finalizer(记住,如果你的类型妥善处理,终结不会被调用,因为你已经叫GC.SuppressFinalize你的Dispose方法).以下程序在应用程序完成时显示调试器输出窗口中的错误,因为Hog未正确处理.
class Program
{
static void Main(string[] args)
{
new Hog( ) ;
}
}
class Hog : IDisposable
{
public void Dispose( )
{
Dispose( true ) ;
GC.SuppressFinalize( this ) ;
}
protected virtual void Dispose( bool disposing )
{
GC.SuppressFinalize( this );
}
~Hog( )
{
Debug.Fail( @"You didn't dispose me!" ) ;
Dispose( false ) ;
}
}
Run Code Online (Sandbox Code Playgroud)
您将在调试器中看到以下错误:
---- DEBUG ASSERTION FAILED ----
---- Assert Short Message ----
You didn't dispose me!
---- Assert Long Message ----
at Hog.Finalize()
Run Code Online (Sandbox Code Playgroud)
但是,如果您确实正确使用了一次性物体,例如:
static void Main(string[] args)
{
using (new Hog())
;
}
Run Code Online (Sandbox Code Playgroud)
......你什么都看不到.
为了使事情更有用,您可以在构造函数中记录当前堆栈跟踪并将其转储到析构函数中.所以新的,更有用的Hog看起来像:
class Hog : IDisposable
{
readonly StackTrace _stackTrace ;
public Hog( )
{
#if DEBUG
_stackTrace = new StackTrace();
#endif
}
public void Dispose( )
{
Dispose( true ) ;
GC.SuppressFinalize( this ) ;
}
protected virtual void Dispose( bool disposing )
{
GC.SuppressFinalize( this );
}
~Hog( )
{
#if DEBUG
Debug.WriteLine("FinalizableObject was not disposed" + _stackTrace.ToString());
#endif
Dispose( false ) ;
}
}
Run Code Online (Sandbox Code Playgroud)
并使用它(不处理它)会在调试器输出窗口中给你这个:
FinalizableObject was not disposed at ConsoleApplication1.Hog..ctor()
at ConsoleApplication1.Program.Main(String[] args)
at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
Run Code Online (Sandbox Code Playgroud)