2010-03-24 66 views
0
public class ABC 
{ 
    public ABC(IEventableInstance dependency) 
    { 
     dependency.ANewEvent += MyEventHandler; 
    } 

    private void MyEventHandler(object sender, EventArgs e) 
    { 
     //Do Stuff 
    } 
} 

让我们说ABC的一个实例是一个长活体对象,并且我的依赖项是一个更长的运行对象。当ABC的实例需要清理时,我有两个选项。处置生活依赖性很大的对象

我可以有一个Cleanup()方法来取消订阅ANewEvent事件,或者我可以实现IDisposable并在Dispose中取消接口事件。现在我无法控制消费者是否会调用dispose方法,或者我应该使用Cleanup方法。

我应该实施终结者并退订吗?它感觉肮脏,但我不希望悬挂ABC的例子。

想法?

回答

1

这个问题的显而易见的解决方案是,在离开这个问题一年之后,我应该实现IDisposable并简单地取消订阅我的Dispose()中的事件。

由于我对依赖关系的生命周期没有责任,因此我无法对它做任何事情。

1

我读到这对MSDN

因为Dispose方法必须 显式调用,对象是 实现IDisposable 还必须 实现一个终结处理 释放资源时,处置不 叫 。默认情况下,垃圾收集器会在回收其内存之前自动调用对象的终结器( )。但是,一旦调用了Dispose 方法,通常不需要垃圾 收集器调用已处理的对象的终结器的 。为了防止 自动完成,Dispose 实现可以调用 GC.SuppressFinalize方法。

因此,在这种情况下,为了安全起见,我会实现IDisposable和终结器。我同意,这有点脏,但是再次,这是您在处理长寿命物体时付出的代价。

+1

但是,仅当我们使用非托管代码时才需要终结器。 – 2011-02-16 10:16:17

+0

@RayBooysen:问题不在于是否使用非托管代码,而在于是否正在使用需要清理的内容,哪些内容可以在终结器的上下文中进行有效清理。在托管代码中有完整的上下文对于清理是必需的,但也有很多地方,即使未调用Dispose会导致问题,终结器也无法帮助解决(例如,因为没有线程安全的清理方法,或者因为需要清理来分离会阻止终结器运行的强引用)。 – supercat 2012-10-23 18:30:12