2012-04-17 7 views
16

Ich weiß, dass Using Anweisung das Objekt, das erstellt wird. Wie, wenn ich wollte, so etwas tun:Catching Exception innerhalb Verwendung der Anweisung

Using(SqlConnection conn = new SqlConnection(connString)) 
    { 
     //some code 
     //How to show the users if conn is not opened up or generated some kind of error? 
    } 

Wie die Benutzer zeigen, wenn conn nicht geöffnet oder irgendeine Art von Fehler generiert?

+0

Surround mit einem TryCatch-Block – SimpleVar

+0

Mit "versuchen/fangen" – Jon

+0

Könnten Sie Ihre Frage klären? Ich bin nicht sicher, was du hier verlangst. – Tejs

Antwort

8

using bietet keine Backdoor in die catch.

einfach erweitern Sie es manuell (kein Punkt die try/catch in der Verwendung von IMO in mit):

SqlConnection conn = null; 

try 
{ 
    conn = new SqlConnection(""); 
} 
catch ... 
{ 

} 
finally 
{ 
    if (conn != null) 
     conn.Dispose(); 
} 

Ich bevorzuge diese über die using in einem try-catch Einwickeln oder eine try-catch im using meisten der Einbettung Zeit zu vermeiden, dass der Code mit einem verschachtelten try-catch einmal kompiliert endet. Wenn Sie nur eine sehr kleine Teilmenge eines großen Stück Code in einem using abdecken müssen, würde ich jedoch granularer sein und es einbetten.

+0

@marc_s Semantik, der Punkt ist, dass 'using' keine Unterstützung bietet, du musst zurückgehen, um zu versuchen/zu fangen. –

+2

@marc_s Mein Weg kompiliert nur einen Versuch/Fang, sonst jeder für sich. Meins bietet nicht weniger Unterstützung als 'using'. –

22

Es gibt nichts besonderes über Code in einem using Block geschrieben - verwenden nur try.catch Ausnahmen zu behandeln:

using(SqlConnection conn = new SqlConnection(connString)) 
{ 
    try 
    { 
     conn.Open(); 
     // do more stuff here...... 

    } 
    catch(SqlException sqlEx) 
    { 
     // log error and possibly show to user in a MessageBox or something else 
    } 
} 

Der using(...) { ... } Block selbst entworfen ist nur, um sicherzustellen, dass die Ressource/Objekt, das es „verkapselt“ wird ordnungsgemäß entsorgt, wenn es nicht mehr benötigt wird. Es gibt nichts, was Sie mit der using-Anweisung selbst tun können, um Fehler zu vermeiden.

Also, wenn Sie erwarten, dass nur das Objekt erstellen könnte scheitern, dann würden Sie den gesamten using Block innerhalb des try ... catch Block oder fallen zurück auf einen try ... catch ... finally Block setzen müssen und gewährleisten die ordnungsgemäße Entsorgung selbst (als Adam schlug in seinem Antworten).

+0

Warum verwenden wir try/catch inside? –

+5

+1 ... es ist nicht nur nicht besonders, sondern sogar eine gute Übung, um try/catch in einer using-Anweisung zu verwenden. Objekte zu disponieren und Ausnahmen zu behandeln sind unterschiedliche Konzepte. –

+2

@Raj Weil ein Versuch/Catch ist, wie Sie eine Ausnahme fangen. Ein Verwenden ist nur ein Versuch/Endlich (ohne einen Haken). Wenn Ihre Frage ist, warum ist es nicht außerhalb der Verwendung, weil das Erstellen der Verbindung wahrscheinlich keinen Fehler verursacht, es zu öffnen ist. – Servy

2

Das ist genauso, wie Sie es ohne tun würden.

using(SqlConnection conn = new SqlConnection(connString)) 
{ 
    try{ 
    //some code 
    } 
    catch(SqlException e) 
    MessageBox.Show(e.Message); 
} 
3

Gerade in gewohnter Weise:

Entweder

try 
{ 
    using(SqlConnection conn = new SqlConnection(connString)) 
    { 
     //some code   
    } 
} 
catch (Exception exc) 
{ 
    //handle error 
} 

oder

using(SqlConnection conn = new SqlConnection(connString)) 
{ 
    try 
    { 
     //some code 
    } 
    catch (Exception exc) 
    { 
     //handle error 
    }     
} 
+0

Was ist der Sinn der Verwendung von Try/Catch im Inneren? –

+2

@Widor: Dies wird nicht behandelt, wenn eine Ausnahme ausgelöst wird 'SqlConnection conn = new ...' – xbonez

+0

Nun, es hängt davon ab, was Sie dort tun - vielleicht möchten Sie eine andere potenzielle Ausnahme (nicht im Zusammenhang mit SQL) beispielsweise. – Widor

0

Sie tun es nicht innerhalb der using

try 
{ 
    using(SqlConnection conn = new SqlConnection(connString)) 
    { 
     // Some code for when "conn" is succesfully instantiated 
    } 
} 
catch (SomeSpecificConnectionInstantiationException ex) 
{ 
    // Use ex to handle a bizarre instantiation exception? 
}  
+0

Sie können versuchen/fangen in der Verwendung schreiben. Ich glaube! –

+1

Sie können, aber keine Ausnahme in der Verwendung Instanziierung – Jodrell

+0

@Jodrell zu fangen Aber eine SqlConnection wird im Allgemeinen nicht eine Ausnahme in seinem Konstruktor werfen. Die einzige Ausnahme, die Sie wahrscheinlich erhalten, ist der Ausdruck für den Parameter. – Servy

8
class SqlConnection 
{ 
    using(sqlConnection) 
    { 

    } 
} 

class Consumer 
{ 
    try 
    { 

    } 
    catch(SqlException) 
    { 

    } 

} 

Es liegt an dem Verbraucher der Klasse zu entscheiden, was mit Ausnahme zu tun ist.

6

Wie andere Antworten angegeben haben, fügen Sie einfach einen normalen Versuch/Fang hinzu.

Aber ich möchte hinzufügen, dass dies die falsch Ort, setzen try/catch, besonders wenn Ihr Ziel „zeigen die Benutzer“ ist eine Nachricht. Lassen Sie die Ausnahme auf dieser Ebene passieren und erlauben Sie, dass der Stack in Code aufsteigt, der besser in der Lage ist, zu wissen, wie Sie darauf reagieren sollen.

Mit anderen Worten, lassen Sie Ihr Codebeispiel wie es ist. Fügen Sie nichts Neues hinzu ... zu dieser Methode. Aber vielleicht sollte der Code, der diese Methode aufruft, darüber nachdenken, wie man eine Ausnahme behandelt ... irgendeine Ausnahme ... von der Datenbank.

+0

Können Sie mir ein Beispiel dafür zeigen? Oder irgendein Link, der ihm genügt. Vielen Dank! –

+0

@Raj Überprüfen Sie meine Antwort. Das habe ich in meiner Antwort erwähnt. – Sandeep

-2

Es empfiehlt sich, try {} catch() {} in der using-Anweisung zu verwenden, wenn Sie eine Ausnahme abfangen wollen, die vom Code im using-Block ausgelöst wird. Betrachten Sie nun die folgenden zwei Beispiele - das erklärt, warum der try-catch-Block in der using-Anweisung eine gute Übung ist.

Beispiel 1

 try{ 
      using(SomeObject so = new SomeObject){ 
       // Perform some tasks 
      } 
     }catch(SomeException objSomeException){ 
      // Perform some actions, if exception occurs 
     } 

Beispiel 2

 using(SomeObject so = new SomeObject){ 
      try{  
       // Perform some tasks 
       }catch(SomeException objSomeException){ 
        // Perform some actions, if exception occurs 
       } 
     } 

Nun, wenn eine Ausnahme während auftritt einige Aufgaben innerhalb der using-Anweisung durchgeführt wird, werden beide haben beispielsweise die gleiche Ergebnisse. Die einfache Antwort ist Nein, Grund ???

Wenn in Beispiel 1 eine Ausnahme auftritt, wird sie vom catch-Block abgefangen - ohne das Ende des using-Blocks zu erreichen. Daher wird das ameObject in Beispiel 1 nicht ordnungsgemäß entsorgt. Selbst wenn CLR großzügig ist (auf das Sie nicht zählen sollten) - der von dem someObject in Beispiel 1 verwendete Speicher wird nicht wiederhergestellt (oder wird maximal in der GC-Sammlung der Generation 2 landen).

Im Fall von Beispiel 2 befindet sich der catch-Block in der using-Anweisung. Das bedeutet, dass die Ausführung das Ende des Verwendungsblocks erreicht. Daher wird Ihr Objekt entsorgt und Sie müssen sich keine Gedanken über das Speicherleck machen (Verderb,

+4

Das ist falsch. Wenn bei der Verwendung ein Fehler auftritt, wird das Objekt durch den impliziten "finally" -Block des "using" entsorgt, und die Ausnahme wird durch den äußeren "catch" verwaltet. Im zweiten Fall wird die Ausnahme durch den inneren 'catch'-Block verwaltet, und das implizite' finally' von 'using' wird es später entsorgen. Der einzige Unterschied besteht darin, dass das Objekt im zweiten Beispiel "catch" noch verfügbar ist, so dass Sie es weiterhin verwenden können, um die Ausnahme zu behandeln. Im ersten Beispiel ist das Objekt im Catch-Block nicht mehr verfügbar. Keine Unterschiede mehr. – JotaBe

0

) Wenn Sie den using() -Block in einen try/catch einbetten, garantiert der using() - Block tatsächlich, dass Dispose Wenn jedoch nicht verwalteter Code irgendwo innerhalb Ihres using-Blocks eine Ausnahme auslöst, wird using() nur essen und es wird Ihren Catch nicht erreichen. Verwenden Sie try/catch innerhalb des using() -Blocks, überspringen Sie using() Versuchen Sie/try/catch/finally, oder benutzen Sie die seltsame Syntax "using() try" mit einem catch-Block (was Sie mit einer ungeraden Anzahl von Klammern belässt und wahrscheinlich die Programmierer der mittleren Ebene verwirren wird, die später darauf stoßen es

Verwandte Themen