如何检查对象是否已经在C#中处置
可能重复:
如何判断是否放置了一个IDisposable对象引用?
有没有一种方法来检查对象是否被处置不同呢
try { myObj.CallRandomMethod(); } catch (ObjectDisposedException e) { // now I know object has been disposed }
在我的情况下,我使用具有Close()
方法的TcpClient
类来处理对象,这可能发生在我无法控制的代码段中。 在这种情况下,我想有更好的解决scheme,然后捕捉exception。
一个好办法是从TcpClient派生并重写Disposing(bool)方法:
class MyClient : TcpClient { public bool IsDead { get; set; } protected override void Dispose(bool disposing) { IsDead = true; base.Dispose(disposing); } }
如果其他代码创build实例,那么这将不起作用。 那么你将不得不做一些绝望的事情,比如使用Reflection来获得私有m_CleanedUp成员的值。 或者赶上例外。
坦率地说,没有一个可能会达到很好的结果。 你真的想写入TCP端口。 但是你不能控制你的代码。 你已经增加了这个bug的影响。 与代码的所有者交谈并且解决问题是迄今为止最好的解决scheme。
可靠的解决scheme是捕获ObjectDisposedException。
因为在调用Dispose方法的线程和访问对象的线程之间存在一个竞争条件:在检查了假设的IsDisposed属性之后,可以真正处理对象,抛出exception都是一样的。
另一种方法可能是暴露一个假设事件Disposed(像这样 ),用来向每个感兴趣的对象通知处理对象,但根据软件devise,这可能是难以计划的。
如果您不确定对象是否已被处置,则应该调用Dispose
方法而不是Close
方法。 尽pipe框架并不能保证Dispose方法必须在没有exception的情况下运行,即使对象之前已经被抛弃了,这也是一个常见的模式,而且我的知识是在框架中的所有可处理对象上实现的。
按照微软的 Dispose
, Dispose
的典型模式是:
public void Dispose() { Dispose(true); // Use SupressFinalize in case a subclass // of this type implements a finalizer. GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { // If you need thread safety, use a lock around these // operations, as well as in your methods that use the resource. if (!_disposed) { if (disposing) { if (_resource != null) _resource.Dispose(); Console.WriteLine("Object disposed."); } // Indicate that the instance has been disposed. _resource = null; _disposed = true; } }
注意_disposed
的检查。 如果您要调用实现此模式的Dispose
方法,则可以根据需要多次调用Dispose,而不会触发exception。
最佳实践说,要使用本地布尔字段自行实现它: http : //www.niedermann.dk/2009/06/18/BestPracticeDisposePatternC.aspx