2010-07-08 6 views
1
try 
{ 
    OpenConnection(); 
    RowsAffected = cmd.ExecuteNonQuery(); 
    CloseConnection(true); //should I use this function call here 
    //as well, when I am using it in finally 
    //block. For closing database connection. 
} 
catch (SqlException ex) 
{ throw ex; } 
finally 
{ CloseConnection(true); } 

Ou devrais-je écrire cette façonSi une fonction être utilisée dans le bloc d'essai qui doit être exécuté dans finally

try 
{ 
    OpenConnection(); 
    RowsAffected = cmd.ExecuteNonQuery(); 
} 
catch (SqlException ex) 
{ throw ex; } 
finally 
{ CloseConnection(true); } 
+2

N'utilisez pas 'throw ex;' car cela effacera la trace de la pile. Utilisez 'throw;' à la place. –

+0

@Oliver Hanappi: vous avez raison à ce sujet mais dans ce cas, je n'essaierais pas d'attraper quoi que ce soit parce que le simple fait d'attraper et de relancer et d'exception sans logique supplémentaire ne fournit aucune valeur. –

+0

À tous: Après avoir regardé vos commentaires. Je pense que vous pourriez également m'aider dans ma question précédente. http://stackoverflow.com/questions/3201606/how-exceptions-are-handled-while-designing-datalayer-or-any-other-layered-archite Je lis des articles sur le mécanisme de gestion des exceptions et je veux connaître le modèle de conception pour gérer l'exception. Ce serait appréciable si vous pouviez m'aider dans une autre question également. –

Répondre

8

Non, le bloc finally obtient toujours exécuté, quel que soit le succès ou échec du code dans le bloc try. Dans votre premier exemple, la connexion serait fermée deux fois en cas de succès.

Vous dites que vous vérifiez l'état de la connexion, ce qui signifie que vous ne recevez pas d'exception lorsque vous fermez deux fois la connexion. Cependant, je pense qu'il est plus approprié d'essayer de le fermer seulement si nécessaire.

+0

Aucun moyen, ne devrait pas écrire dans le bloc try? Je vérifie l'état de la connexion avant la fermeture. –

+0

@Shantanu Gupta: c'est correct. –

+2

Juste un peu de trivia que je suis tombé récemment - enfin les blocs ne sont pas * toujours * appelés. Voir Environment.FailFast (http://msdn.microsoft.com/en-us/library/ms131100.aspx) –

0

Votre bloc finally est toujours exécuté. Utiliser les fonctions Close comme Dispose(), FERMEZ() devrait utiliser dans finally

0

Vous devriez écrire dans la deuxième voie

   try 
       { 
        OpenConnection(); 
        RowsAffected = cmd.ExecuteNonQuery(); 
       } 
       catch (SqlException ex) 
       { throw ex; } 
       finally 
       { CloseConnection(true); } 
1

Dans cet exemple particulier, vous pouvez en effet faire:

using (var conn = new SqlConnection(...)) { 
    // Do work 
} 

ce que le compilateur fait avec cette déclaration est essentiellement:

SqlConnection conn; 
try { 
    conn = new SqlConnection(...) 
} finally { 
    conn.Dispose(); 
} 

ou à peu près s ... le bloc finally est toujours exécuté, ce qui garantit qu'un bloc using appelle toujours Dispose.

L'inconvénient de cette approche est que vous ne pouvez pas attraper le SqlException qui pourrait être jeté, si vous finissez par faire quelque chose comme ceci:

try { 
    using (var conn = new SqlConnection(...)) { 
    // Do work. 
    } 
} catch (SqlException ex) { 

} 

Mais le code compilé finit par représenter:

try { 
    SqlConnection conn; 
    try { 
    conn = new SqlConnection(...); 
    } finally { 
    conn.Dispose(); 
    } 
} catch (SqlException ex) { 

} 

Pour être honnête, cela ne fera probablement aucune différence en termes de performances, car à chaque fois que vous lancez une exception, ce sera un coup de performance. Cela garantit que Dispose est toujours appelé.

Questions connexes