从事件处理程序调用实例上的Dispose是否安全?

时间:2013-04-05 14:39:29

标签: c#-4.0 idisposable

public class MyTask : IDisposable { ... }

MyTask task = new MyTask(() => SomeTask);

task.Completed += (s, e) =>
{
    // do something with result
    ...
    // dispose of this instance
    ((MyTask)s).Dispose();
};

// execute the task
task.Execute();

显然我无法确定任务何时完成,所以我可以处理此实例的唯一实际位置是已完成事件。

这样做安全吗?

1 个答案:

答案 0 :(得分:0)

对于何时可以安全地呼叫Dispose,没有一般规则。如果Microsoft指定在不使用对象的任何时候Dispose必须是安全的,那么遵守这样的规则很少会很困难;在类可能不总是能够立即执行所有必要的清理(*)的情况下,通常可以设置标志和/或以其他方式安排在下一次机会时执行必要的清理。不幸的是,Microsoft没有指定Dispose实现必须处理异步Dispose请求,也没有任何通用方法来保存对IDisposable实例的最后一个有用引用的对象要求处理时可以安全通知。

尽管一般都不能确定何时可以安全地调用Dispose,但许多实现Dispose的特定类确实可以确保何时可以安全地调用它。如果知道特定对象是可以在特定上下文中安全地处置的类型,则可以将其丢弃。特别是在来自对象的事件可能是Dispose它在线程上下文中唯一可以了解它的机会的情况下,并且在事件处理程序中处理对象的位置是有意义的,处理它应该是安全的。物体。应该准备好任何正确编写的事件处理程序,以便发送事件的对象可以在系统决定它们应该运行的时间和它实际运行它们的时间之间进行处理。

(*)IDisposable的基本目的是允许一个对象通知其外部但代表它的行为损害其他实体的实体,他们不应再这样做[例如]告诉文件系统它不应该再授予对象对文件的独占访问权限]。这种行为被称为“释放资源”。有人持有对象的最后一个幸存引用这一事实可能意味着没有其他线程可以使用该对象,但并不意味着没有其他线程正在使用其资源需要被释放的任何非线程安全实体。