【发布时间】:2010-02-24 01:49:01
【问题描述】:
我想提供一个类来管理临时目录的创建和后续删除。理想情况下,我希望它可以在 using 块中使用,以确保无论我们如何离开块,目录都会再次被删除:
static void DoSomethingThatNeedsATemporaryDirectory()
{
using (var tempDir = new TemporaryDirectory())
{
// Use the directory here...
File.WriteAllText(Path.Combine(tempDir.Path, "example.txt"), "foo\nbar\nbaz\n");
// ...
if (SomeCondition)
{
return;
}
if (SomethingIsWrong)
{
throw new Exception("This is an example of something going wrong.");
}
}
// Regardless of whether we leave the using block via the return,
// by throwing and exception or just normally dropping out the end,
// the directory gets deleted by TemporaryDirectory.Dispose.
}
创建目录没问题。问题是如何编写 Dispose 方法。当我们尝试删除目录时,我们可能会失败;例如,因为我们仍然在其中打开了一个文件。但是,如果我们允许异常传播,它可能会掩盖在 using 块内发生的异常。特别是,如果在 using 块内发生异常,可能是导致我们无法删除目录,但如果我们屏蔽它,我们就丢失了修复问题的最有用信息.
看来我们有四个选择:
- 在尝试删除目录时捕获并吞下任何异常。我们可能没有意识到我们未能清理临时目录。
- 以某种方式检测 Dispose 是否在引发异常时作为堆栈展开的一部分运行,如果是,则抑制 IOException 或引发合并 IOException 和引发的任何其他异常的异常。甚至可能都不可能。 (我之所以想到这一点,部分原因是它可以使用 Python 的 context managers,它在很多方面类似于与 C# 的 using 语句一起使用的 .NET 的 IDisposable。)
- 永远不要抑制 IOException 无法删除目录。如果在 using 块中抛出异常,我们将隐藏它,尽管它很有可能比我们的 IOException 具有更多的诊断价值。
- 放弃在 Dispose 方法中删除目录。该类的用户必须继续负责请求删除目录。这似乎不能令人满意,因为创建类的很大一部分动机是减轻管理此资源的负担。也许还有另一种方法可以提供此功能而不会很容易搞砸?
这些选项之一显然是最好的吗?有没有更好的方法在用户友好的 API 中提供此功能?
【问题讨论】:
标签: c# idisposable temporary-directory