2010-04-28 6 views
7

Avoir un bloc mental aujourd'hui, besoin d'une main vérifiant ma logique n'est pas fubar'ed.Disposables, en utilisant & Try/Catch Blocks

Traditionnellement je ferais fichier i/o semblable à ceci:

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

Cependant, ce n'est pas très élégant.

Idéalement, je voudrais utiliser le bloc using pour disposer du flux de fichiers lorsque j'ai terminé, mais je ne suis pas sûr de la synergie entre l'utilisation et try/catch.

Voilà comment je voudrais mettre en œuvre ce qui précède:

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

Cependant, je suis inquiet qu'une sortie prématurée (par exception levée) à l'intérieur du bloc à l'aide ne peut pas permettre au bloc à l'aide de terminer l'exécution et nettoyer son objet. Suis-je simplement paranoïaque, ou est-ce que cela fonctionnera comme je le souhaite?

Répondre

17

Vous êtes juste être paranoïaque et il fonctionnera de la façon dont vous avez l'intention de :)

Une déclaration à l'aide équivaut à un bloc try/finally, que ce soit dans un try/catch ou non.

Ainsi, votre code est similaire à:

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

Ne vous inquiétez pas, il va nettoyer comme prévu et est plus propre que l'original.

En fait, il est beaucoup plus commun d'avoir une instruction try/finally aka using dans votre logique métier, et un try/catch dans un gestionnaire de niveau supérieur dans le niveau d'interface utilisateur ou physique. Quelque chose comme:

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

et

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

Cela fonctionne - en interne l'instruction à l'aide compile de la même façon que d'essayer-finally

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

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

deuxième morceau de code est traduit en ce

0

Le bloc using fonctionnera exactement comme vous l'entendez traduire le bloc using est réel ment juste

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

Vous n'avez pas besoin try..finally si vous avez un using(). Ils effectuent la même opération.

Si vous n'êtes pas convaincu, pointez Reflector sur votre assemblage et comparez le code généré.

Questions connexes