Disposables, Using & Try/Catch Blocks

有些话、适合烂在心里 提交于 2020-01-10 03:52:05

问题


Having a mental block today, need a hand verifying my logic isn't fubar'ed.

Traditionally I would do file i/o similar to this:

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();
}

However, this isn't very elegant.

Ideally I'd like to use the using block to dispose of the filestream when I'm done, however I am unsure about the synergy between using and try/catch.

This is how i'd like to implement the above:

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

However, I'm worried that a premature exit (via thrown exception) from within the using block may not allow the using block to complete execution and clean up it's object. Am I just paranoid, or will this actually work the way I intend it to?


回答1:


You're just being paranoid and it will work the way you intend it to :)

A using statement is equivalent to a try/finally block, whether it's inside a try/catch or not.

So your code is similar to:

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



回答2:


Don't worry, it will clean up as expected and is cleaner than your original.

In fact it's much more common to have a try/finally aka using statement in your business logic, and a try/catch in a top-level handler in the UI tier or at a physical tier boundary. Something like:

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

and

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



回答3:


This will work - internally the using statement compiles the same way as a try-finally block




回答4:


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

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

second piece of code gets translated into this




回答5:


The using block will work exactly as you entend translated the using block is really just

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



回答6:


You don't need the try..finally if you have a using(). They perform the same operation.

If you're not convinced, point Reflector at your assembly and compare the generated code.



来源:https://stackoverflow.com/questions/2732063/disposables-using-try-catch-blocks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!