我有一个类(比如MyClass
)使用(作为私有字段)一个TcpClient
对象。 MyClass
在IDisposable
方法中实施了TcpClient.Close
Dispose
。
我的问题是MyClass
还应该实现终结器调用Dispose(bool Disposing)
以释放TcpClient’s
非托管资源,以防调用代码调用MyClass.Dispose
吗?
由于
答案 0 :(得分:4)
不,你不应该。
因为你永远不应该在终结器中的其他对象上调用方法,所以它可能已经在你的对象之前完成了。
垃圾收集器将调用TcpClient的终结器,所以让他这样做。
Dispose中的模式是:
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
// dispose managed resources (here your TcpClient)
}
// dispose your unmanaged resources
// handles etc using static interop methods.
}
答案 1 :(得分:2)
不,你不应该。
来自this优秀帖子:
最终确定是基本的 与结束对象不同 一生。从正确的角度来看 看来,之间没有任何顺序 终结者(特殊情况之外) 对于关键终结者),所以如果你 有两个GC认为的对象 在死的同时,你不能 预测哪个终结器将完成 第一。这意味着你不能拥有 与任何人交互的终结者 存储在实例中的可终结对象 变量
这是我对一次性/终结模式的参考实现,其中的注释解释了何时使用:
/// <summary>
/// Example of how to implement the dispose pattern.
/// </summary>
public class PerfectDisposableClass : IDisposable
{
/// <summary>
/// Type constructor.
/// </summary>
public PerfectDisposableClass()
{
Console.WriteLine( "Constructing" );
}
/// <summary>
/// Dispose method, disposes resources and suppresses finalization.
/// </summary>
public void Dispose()
{
Dispose( true );
GC.SuppressFinalize(this);
}
/// <summary>
/// Disposes resources used by class.
/// </summary>
/// <param name="disposing">
/// True if called from user code, false if called from finalizer.
/// When true will also call dispose for any managed objects.
/// </param>
protected virtual void Dispose(bool disposing)
{
Console.WriteLine( "Dispose(bool disposing) called, disposing = {0}", disposing );
if (disposing)
{
// Call dispose here for any managed objects (use lock if thread safety required), e.g.
//
// if( myManagedObject != null )
// {
// myManagedObject.Dispose();
// myManagedObject = null;
// }
}
}
/// <summary>
/// Called by the finalizer. Note that if <see cref="Dispose()"/> has been called then finalization will
/// have been suspended and therefore never called.
/// </summary>
/// <remarks>
/// This is a safety net to ensure that our resources (managed and unmanaged) are cleaned up after usage as
/// we can guarantee that the finalizer will be called at some point providing <see cref="Dispose()"/> is
/// not called.
/// Adding a finalizer, however, IS EXPENSIVE. So only add if using unmanaged resources (and even then try
/// and avoid a finalizer by using <see cref="SafeHandle"/>).
/// </remarks>
~PerfectDisposableClass()
{
Dispose(false);
}
}
答案 2 :(得分:1)
不,你不必。 TcpClient是一个围绕非托管套接字的包装类,它的管理方式就是应该处理它。你所做的就足够了。
答案 3 :(得分:0)
是的,你应该 - Microsoft even recommends it。
请记住,腰带和吊带代码永远不会让你在凌晨2点被叫到办公室:)