可释放对象、使用和Try/Catch块

7

今天有点脑子不太灵光,需要帮忙验证一下我的逻辑是否正确。

传统上我会像这样进行文件 I/O 操作:

FileStream fs = null; // So it's visible in the finally block
try
{
   fs = File.Open("Foo.txt", FileMode.Open);

   /// Do Stuff
}
catch(IOException)
{
   /// Handle Stuff
}
finally
{
   if (fs != null)
      fs.Close();
}

然而,这种方法并不优雅。

理想情况下,我希望使用using块来在完成后释放文件流,但是我不确定usingtry/catch之间的协同作用。

以下是我想要实现上述功能的方式:

try
{
   using(FileStream fs = File.Open("Foo.txt", FileMode.Open))
   {
      /// Do Stuff
   }
}
catch(Exception)
{
   /// Handle Stuff
}

然而,我担心在using块内部通过抛出异常导致过早退出可能不允许using块完成执行并清理其对象。我是多虑了吗?还是我的意图可以实现?

6个回答

17

你只是过于自卑了,而且它会按照你打算的方式工作 :)

using语句等效于try/finally块,无论它是否在try/catch内部。

所以你的代码类似于:

try
{
   FileStream fs = null;
   try
   {
       fs = File.Open("Foo.txt", FileMode.Open);
       // Do stuff
   }
   finally
   {
       if (fs != null)
       {
           fs.Dispose();
       }
   }
}
catch(Exception)
{
   /// Handle Stuff
}

0

不用担心,它会按预期进行清理,并且比您的原始代码更干净。

事实上,在业务逻辑中使用try/finally(又称为using语句),在UI层或物理层边界的顶层处理程序中使用try/catch是更常见的做法。例如:

try
{
    DoStuffWithFile("foo.txt");
}
catch(Exception ex)
{
   ...
}

并且

public void DoStuffWithFile(string fileName)
{
    using(FileStream fs = File.Open(fileName,...))
    {
        // Do Stuff
    }
}

0
    try
    {
        FileStream fs = null;
        try
        {
           fs = File.Open("Foo.txt", FileMode.Open);

        }
        finally
        {
           fs.Dispose();
        }
    }
    catch(Exception)
    {
       /// Handle Stuff
    }

第二段代码将被翻译为:


0

使用块将按照您的意图工作。翻译一下,使用块实际上只是这样。

try
{
   FileStream fs = null;
   try
   {
        fs = File.Open("Foo.txt", FileMode.Open))
        //Do Stuff
   }
   finally
   {
      if(fs != null)
          fs.Dispose();
   }
}
catch(Exception)
{
   /// Handle Stuff
}

0

这将起作用 - 在内部,using语句的编译方式与try-finally块相同


0

如果你使用using(),就不需要try..finally了。它们执行相同的操作。

如果你还不确定,可以将Reflector指向你的程序集并比较生成的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接