C# 你能开一个”吗;“处置”;如果终结器调用了Dispose(),则返回事件?
我注意到MSDN()上有一些类有一个带有以下注释的C# 你能开一个”吗;“处置”;如果终结器调用了Dispose(),则返回事件?,c#,events,garbage-collection,dispose,idisposable,C#,Events,Garbage Collection,Dispose,Idisposable,我注意到MSDN()上有一些类有一个带有以下注释的Disposing事件: 在调用Dispose或垃圾收集器完成并收集此对象时发生 我想在我的类中实现我自己的处理事件。下面是我的基本实现(): 有人在我的代码审查中提到,他们不确定触发这样的事件是否安全,因为Dispose()可能会从终结器中调用,但是,根据我在顶部添加的MSDN链接上的注释,很明显,当事件被释放或终结时,会有对象触发事件 我是错过了什么还是安全了?如何实现从dispose或最终确定时触发的事件?如果答案是“不,你永远不能这样做”
Disposing
事件:
在调用Dispose或垃圾收集器完成并收集此对象时发生
我想在我的类中实现我自己的处理事件。下面是我的基本实现():
有人在我的代码审查中提到,他们不确定触发这样的事件是否安全,因为Dispose()
可能会从终结器中调用,但是,根据我在顶部添加的MSDN链接上的注释,很明显,当事件被释放或终结时,会有对象触发事件
我是错过了什么还是安全了?如何实现从dispose或最终确定时触发的事件?如果答案是“不,你永远不能这样做”,那么还有其他方法可以达到同样的效果吗?(正在处理或最终确定的对象的事件)如果要在Dispose
方法中执行任何涉及其他对象的操作,则只能在显式调用Dispose
时执行,而不是在从最终确定器调用时执行
原因是,如果其他对象也符合收集条件,则无法保证该对象尚未最终确定。您应该使用标准的建议实现和模式,如命名和约定,而不是自己滚动。特别是,你应该使用bool disposing
而不是bool from finalizer
@LasseV.Karlsen当然,我改变了名字。你可能想阅读Eric Lipperts的帖子,了解在finalizers中可能发生的所有奇怪情况。如果disposing为false,永远,永远不要引发事件。您负担不起从终结器运行任意代码,它不会导致问题的可能性非常低。Dispose事件只有在您能够保证Dispose()方法将被调用时才是合理的。除非类对象完全在您的控制之下,@HansPassantGraphicsDevice
如何实现在释放或最终确定时可以触发的事件?它是由微软实施的;我可以想象,如果它有问题,它会被注意到。那么像我链接的GraphicsDevice
这样的东西是如何产生一个事件的,它说“当调用Dispose或当这个对象完成时”会被触发的呢?如果我能保证订阅者的寿命比出版商长呢?你可以很容易地编写代码来做到这一点,但这样做既不推荐,也不一定安全。因此,我对微软制作的类如何实现它感到困惑。我发现很难相信XNA框架中内置的功能,如GraphicsDevice
和StorageContainer
能够做到这一点,但没有注意到这些事件在任何地方都不安全。如果答案是“不,你永远做不到”,那么还有其他方法可以达到同样的效果吗?我没说你做不到。我说你不应该。你问的是一般性问题,你会得到一般性的答案。如果您有特定的类,您可以通过这样的方式编程,即对最终确定的对象调用Dispose可以保证安全,那么就开始吧。一般的建议是不要这样做。如果你设法使终结线程崩溃,你的应用程序可能会失败。
public abstract class Handle : IDisposable
{
public bool Disposed { get; private set; }
public event System.Action DisposingCompleted;
public Handle()
{
Disposed = false;
}
~Handle()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing = false)
{
if (Disposed)
{
return;
}
if (disposing)
{
HandleManagedResources();
}
HandleUnManagedResources();
Disposed = true;
if (DisposingCompleted != null)
{
DisposingCompleted();
}
}
protected virtual void HandleManagedResources() {}
protected virtual void HandleUnManagedResources() {}
}