webForumDet fria alternativet

Kör finally när man kör return inuti try

.NET

9 svar · 779 visningar · startad av Addeladde

Medlem sedan jan. 20013 406 inlägg
Frågan#1

Körs db.Close() i denna sats?

DBAccess db = new DBAccess()
        try
        {
            return "";
        {
        catch
        {
            return "";
        }
        finally
        {
            db.Close();
            db.Dispose();
        }
Medlem sedan mars 20007 896 inlägg
#2

Ja.

Medlem sedan maj 20012 812 inlägg
#3

- En sak att tänka på är att instansieringen av din DBAccess bör ligga inom try-catch eftersom det kan inträffa fel när den skall skapas.

- Dessutom så bör du kontrollera så att db är skillt från null innan du kallar på .Dispose().

- Close() och Dispose() skall båda göra samma sak, så det räcker att man kallar på den ena av dem. Jag brukar alltid ta som vana att anropa på Dispose() där det finns en sådan metod, och close() när det inte finns en Dispose() metod.

- M

Medlem sedan aug. 20039 340 inlägg
#4

Varför skulle db.Close() köras? return betyder ju att funktionen lämnas, vilket i detta fall sker i try och catch, alltså innan finally körs. Visserligen har jag itne provkört koden, men om inte ASP är helt vrickat konstruerat borde svaret vara nej!

Medlem sedan feb. 20002 300 inlägg
#5

nitro2k01 skrev:

Varför skulle db.Close() köras? return betyder ju att funktionen lämnas, vilket i detta fall sker i try och catch, alltså innan finally körs. Visserligen har jag itne provkört koden, men om inte ASP är helt vrickat konstruerat borde svaret vara nej!

För att finally alltid körs oavsett om du har en return eller inte. Det är inget specifikt för ASP utan gäller i C++, Java, C#, osv.

Och för att förtydliga så kommer först return att göras och sedan kommer metoderna i finally köras.

Medlem sedan jan. 20013 406 inlägg
#6

Gladh skrev:

- En sak att tänka på är att instansieringen av din DBAccess bör ligga inom try-catch eftersom det kan inträffa fel när den skall skapas.

- Dessutom så bör du kontrollera så att db är skillt från null innan du kallar på .Dispose().

- Close() och Dispose() skall båda göra samma sak, så det räcker att man kallar på den ena av dem. Jag brukar alltid ta som vana att anropa på Dispose() där det finns en sådan metod, och close() när det inte finns en Dispose() metod.

- M

Visa gärna lite exmepl på hur du brukar anroppa databaser. Om jag lägger öppningen av DB inom try satsen så kan jag ju inte stänga den i finally?

Medlem sedan jan. 2008280 inlägg
#7

Addeladde skrev:

Visa gärna lite exmepl på hur du brukar anroppa databaser. Om jag lägger öppningen av DB inom try satsen så kan jag ju inte stänga den i finally?

Jo, det borde väl gå om du deklarerar variabeln utanför try/catch, men instansierar innanför?

Men Gladh har säkert bättre tips!

Medlem sedan mars 20007 896 inlägg
#8

Är det inte meningen att objekt som har Close()- samt Dispose()-metoder ska inslutas i en using-sats? Då behöver man inte tänka på såna här triviala saker.

using(SqlDataAdapter da = new SqlDataAdapter()) {
   ...
}

Man behöver alltså inte anropa da.Close() eller da.Dispose() i det här fallet.

Medlem sedan maj 20012 812 inlägg
#9

Precis som invecklaren skriver så skapar du din variable utanför try-catch, men själva instansieringen sker inom try-catch. Du måste dock sätta den till NULL i din deklaration, annars kommer kompilatorn gnälla på dig att din variabel inte är instanserad.


DBAccess db = null;
try
{
 db = new DBAccess;
 ...

}catch(SPECIFIK_EXCEPTION e)
{
 ...
}
finally
{
 if(db != null)
    db.Dispose();
}

Och precis som Spin säger så är det bättre att använda sig av using än en try-catch om det är så att du bara vill vara säker på att saker och ting stängs ner på ett korrekt sätt. Men det finns ju tillfällen då man faktiskt vill att olika saker skall ske om man får ett oväntat fel, och då måste man använd sig av try-catch...

- M

Medlem sedan dec. 19996 721 inlägg
#10

SPiN skrev:

Är det inte meningen att objekt som har Close()- samt Dispose()-metoder ska inslutas i en using-sats?

Det är inte nödvändigtvis meningen, men det är ett snyggt, tydligt och effektivt sätt. Det ersätter inte eventuellt specific catch-hantering man gör, utan motsvarar ett try-finally-block, utan catch.

using (DBAccess db = new DBAccess())
{ 
       //gör saker
}

Det förutsätter dock att DBAccess anropar Close i Dispose, eftersom det bara är Dispose som anropas i slutet av en using.

271 ms totalt · 4 externa anrop · v20260731065814-full.2f471f9e
126 ms — deklarationer (db)
0 ms — hämta statistik (cache)
141 ms — hämta tråd, inlägg och bilagor (db)
127 ms — ändringar (db)