方法返回一个IDisposable-即使没有将结果分配给任何对象,我也应该处置该结果吗? [英] Method returns an IDisposable - Should I dispose of the result, even if it's not assigned to anything?

查看:86
本文介绍了方法返回一个IDisposable-即使没有将结果分配给任何对象,我也应该处置该结果吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这似乎是一个相当简单的问题,但是经过一番搜索之后,我找不到这个特殊的用例.

假设我有一个简单的方法,例如,确定某个进程是否打开了文件.我可以这样做(不是100%正确,但是相当不错):

public bool IsOpen(string fileName)
{
  try
  {
    File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
  }
  catch
  {
    // if an exception is thrown, the file must be opened by some other process
    return true;
  } 
}

(显然,这不是确定此错误的最佳方法,甚至不是正确的方法-File.Open抛出许多不同的异常,它们的含义不同,但适用于此示例)

现在,File.Open调用返回一个FileStream,并且FileStream实现IDisposable.通常,我们希望将所有FileStream实例化的用法包装在using块中,以确保正确处理它们.但是,如果我们实际上没有将返回值分配给任何东西,会发生什么呢?是否仍然需要像这样处理FileStream:

try
{
  using (File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
  { /* nop */ }
}
catch 
{
  return true;
}

我应该创建一个FileStream实例并将其处置吗?

try
{
  using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
}
...

还是这些完全不必要?我们可以简单地调用File.Open而不将其分配给任何东西(第一个代码示例),然后让GC立即处理它吗?

解决方案

是的,您绝对应该丢弃FileStream.否则,该流将保持打开状态,并且在终结器发生清理之前,该文件将无法使用.

这里重要的是所有权:对于File.Open,假定调用方拥有"返回给它的流-如果您拥有实现IDisposable的内容,则是您的责任处理它.

将此与Image.FromStream的情况进行比较:在这种情况下,您传入一个流,然后Image假定 it 拥有该流.在这种情况下,您不必自己关闭流-完成后必须丢弃图像,它将丢弃流.

调用一个静态方法,该方法将返回一次性的几乎总是假定调用者获得了资源的所有权.同上构造函数(实际上是静态方法.)

在这种情况下具有讽刺意味的是,如果您不处理File.Open返回的流,则会发现该文件是可用的-同时使该文件直到不确定的时间才可用. /p>

This seems like a fairly straightforward question, but I couldn't find this particular use-case after some searching around.

Suppose I have a simple method that, say, determines if a file is opened by some process. I can do this (not 100% correctly, but fairly well) with this:

public bool IsOpen(string fileName)
{
  try
  {
    File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None);
  }
  catch
  {
    // if an exception is thrown, the file must be opened by some other process
    return true;
  } 
}

(obviously this isn't the best or even correct way to determine this - File.Open throws a number of different exceptions, all with different meanings, but it works for this example)

Now the File.Open call returns a FileStream, and FileStream implements IDisposable. Normally we'd want to wrap the usage of any FileStream instantiations in a using block to make sure they're disposed of properly. But what happens in the case where we don't actually assign the return value to anything? Is it still necessary to dispose of the FileStream, like so:

try
{
  using (File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
  { /* nop */ }
}
catch 
{
  return true;
}

Should I create a FileStream instance and dispose of that?

try
{
  using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.None));
}
...

Or are these totally unnecessary? Can we simply call File.Open and not assign it to anything (first code example), and let the GC dispose of it right away?

解决方案

Yes, you should definitely dispose of the FileStream. Otherwise the stream will remain open and the file won't be usable until a finalizer happens to clean it up.

The important thing here is ownership: for File.Open, the caller is assumed to "own" the stream returned to it - and if you own something which implements IDisposable, it's your responsibility to dispose of it.

Compare this with the situation of Image.FromStream: in that case, you pass in a stream and the Image then assumes that it owns that stream. You mustn't close the stream yourself, in that case - you have to dispose of the image when you're done, and it will dispose of the stream.

Calling a static method which returns something disposable almost always assumes that the caller takes ownership of the resource. Ditto constructors (which are effectively static methods.)

The irony in this case is that if you don't dispose of the stream returned by File.Open, you'll have found that the file is usable - at the same time as making it unusable until some indeterminate time.

这篇关于方法返回一个IDisposable-即使没有将结果分配给任何对象,我也应该处置该结果吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆