流的通用IDisposable包装器 - 替代捕获所有异常

时间:2011-04-12 16:20:31

标签: c# .net

所以我刚刚为一个抽象文件并在其包含的流上实现IDisposable的类型编写了这个实现。它旨在用于任何项目:

public void Dispose()
{
  if (_contentStream == null)
    return;
  lock (_contentStreamLocker)
  {
    if (_contentStream == null)
      return;

    try
    {
      _contentStream.Dispose();
    }
    catch (Exception)
    {
      //legitimate? - don't let any exception prevent 
      //us from successfully disposing?
    }  
    _contentStream = null;
  }
}

所以我觉得很脏,因为:

  • 我正在追赶Exception
  • 我对Exception
  • 一无所知

但是因为我不能保证底层流的行为(也考虑到自定义实现) - 即如果它已经被处置或者它处于实现决定处理是不可能的状态 - 我真的看不出是什么别的事。

显然我不应该隐藏Stream的{​​{1}}的不良实现;但我认为这里有一个中途宿舍。

特别是这个对象不一定“拥有”流,因此不必总是对Dispose()负责。因此,它应该容忍流被其他人处置的时间。

显然,在大多数情况下,这不是问题;或许在Dispose()块中获取一个文件,阅读它,用它做一些事情然后处理它。但是那些边缘情况;他们打扰我了!

最初我把它写成using - 但这只是一种不能依赖的非正式模式。

我该怎么办?保持这样,尽管异常吞咽是不好的业力? Gulp 只有 catch(ObjectDisposedException){ },即使那不是更好吗?或者我应该没有任何例外吞咽或处理?

我可以在所有情况下看到优点;只是无法弄清楚哪一个获胜。

3 个答案:

答案 0 :(得分:3)

一般来说,如果你无法弄清楚哪一个获胜,那是因为将会有一些无法“一般”处理的有用信息。在这种情况下,我认为最好让呼叫者处理它,因为它们将处于一个允许他们更好地判断的具体情况中。

如何将流引入此类?如果你可以设计这样的传递方式,那么为什么不让呼叫者处理它而不关心它。 StreamReader承担这一责任总是让我感到困惑。如果没有,我不会在乎。

不要SWOWOW 异常,特别是在用于外部消费的代码中。

答案 1 :(得分:2)

正如您所说,如果您不拥有一次性用品,则不应将其丢弃你甚至不应该被称为Dispose。

在这里查看我的答案。

Disposing of arguments for an iterator block


更新

好吧,你是否拥有一次性用品的问题并没有由创造一次性用品的人来回答。所有权可以传递给其他类。一旦流传递给它,StreamReader承担所有权。因此,流的创建者不必调用dispose,并且可以依赖StreamReader来执行此操作。

答案 2 :(得分:1)

我建议您根据Microsoft guidelines实现您的配置模式。如果您的包装器的客户端已经“拉出地毯”基础流,您应该让异常到达它们以便他们可以处理用它,或者至少知道它。