[VB.net]nut van try/catch

Pagina: 1
Acties:

  • gill
  • Registratie: Januari 2002
  • Laatst online: 26-12-2025

gill

Love my lindsey...

Topicstarter
Ik ben op't werk een programma aan't schrijven in vb.net.
Persoonlijk gebruik ik vaak try/catch constructies: rond een lijn code die een file leest die er mss niet is, wanneer een webservice niet antwoordt...

Maar de projectleider gaat hier nog een stuk verder in, en daar stel ik me vragen bij. Volgens hem moet elke lijn code binnen een try/catch staan...
me.hide van een Form moet in een try/catch, want je weet niet wat die Hide() allemaal doet, en dus kan falen.
Dim a as dataset
a = new DataSet()
Moet ook in een try/catch, want er kan een memory tekort optreden en dan faalt de code...
En zo ontstaat er dus zeer onoverzichtelijke code, want je krijgt een hoop geneste try/catch blokken.

Voor zover ik weet, runt .net altijd in 1 groot try/catch blok, dat alle niet-opgevangen fouten afhandelt. En maken al deze constructies de code niet trager qua uitvoering?

Ik wou daarom eens weten wie ook op deze manier codeert. Vind je het nodig of net overbodig om voor code als in de voorbeelden errorhandling-blokken toe te voegen?

Visit my new Blog!
www.Snowball.be


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-05 23:34
Hm, niet iedere lijn code moet rond een try - catch blok staan.

Blokken code die samenhangen kan je in een try / catch blok zetten. Als er daar iets in faalt, wordt dat opgevangen door één van de catch() clausules. (Een try kan meerdere catch-blokken hebben).

Excepties die niet opgevangen worden, kan je (in winforms) alsnog opvangen als je een event-handler creeërt voor de Application.ThreadException event.

https://fgheysels.github.io/


  • gill
  • Registratie: Januari 2002
  • Laatst online: 26-12-2025

gill

Love my lindsey...

Topicstarter
Idd. Maar zou jij nu een aparte try/catch gaan schrijven rond bv a = new DataSet() ?

Visit my new Blog!
www.Snowball.be


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-05 23:34
gill schreef op 07 oktober 2004 @ 09:39:
Maar de projectleider gaat hier nog een stuk verder in, en daar stel ik me vragen bij. Volgens hem moet elke lijn code binnen een try/catch staan...

[...]


[...]
Wat een onzin.
Als een lege dataset creeëren al voor een tekort aan geheugen kan zorgen.... Trouwens, als er een tekort aan geheugen is, gaat de GC wel kijken of er geheugen kan vrijgemaakt worden; indien dit niet het geval is, dan wordt er een exception gegooid.
Voor zover ik weet, runt .net altijd in 1 groot try/catch blok, dat alle niet-opgevangen fouten afhandelt. En maken al deze constructies de code niet trager qua uitvoering?
Het catchen van een exceptie zorgt niet voor overhead, maar het gooien van een exceptie wel.
Ik wou daarom eens weten wie ook op deze manier codeert.
Ik iig niet. Een try catch blok rond iedere lijn code (afzonderlijk) is kwatsch.
Een try/catch blok rond een blok code dat kan falen; ok, maar niet iedere lijn afzonderlijk:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
FileStream fs = null;
StreamWriter wr = null;
try
{
      fs = new FileStream ( .... );
      wr = new StreamWriter (fs);

       ....
}
catch( IOException ex )
{
    // do something
}
catch( Exception ex )
{
    // do something.

}
finally
{
   wr.Close();
}

https://fgheysels.github.io/


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-05 23:34
gill schreef op 07 oktober 2004 @ 09:44:
Idd. Maar zou jij nu een aparte try/catch gaan schrijven rond bv a = new DataSet() ?
Nee, zeker niet, want als dat faalt, zal het catch blok wel uitgevoerd worden, maar de volgende lijn code (die die dataset bv. gebruikt) zal dan ook uitgevoerd worden, etc...
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
DataSet ds;
try
{
   ds = new DataSet();
}
catch( Exception ex )
{
}

try
{
    da.Fill (ds);
}
catch( )
{
}

Als die 'new DataSet' faalt, dan wordt de catch uitgevoerd, maar zal de da.Fill ook uitgevoerd worden. Dat wil je dus niet.
Als de creatie van de dataset faalt, dan wil je dat de verdere uitvoering van de rest van de code die daar iets mee te maken heeft, ook niet uitgevoerd wordt.
Als die 2 lijnen in één try blok staan, en er treedt een exceptie op bij de creatie van de dataset, dan wordt er naar de catch gesprongen, en dat is wat je wilt imo.

https://fgheysels.github.io/


  • gill
  • Registratie: Januari 2002
  • Laatst online: 26-12-2025

gill

Love my lindsey...

Topicstarter
Wat een onzin.
Als een lege dataset creeëren al voor een tekort aan geheugen kan zorgen.... Trouwens, als er een tekort aan geheugen is, gaat de GC wel kijken of er geheugen kan vrijgemaakt worden; indien dit niet het geval is, dan wordt er een exception gegooid.
Het is net het feit dat er geen geheugen meer zou vrij zijn bv dat hij wil ontwijken, dmv een try/catch er rond te zetten.
Het catchen van een exceptie zorgt niet voor overhead, maar het gooien van een exceptie wel.
Maar wordt de code niet logger hierdoor? Zoveel geneste blokken edm, maakt dat de executie niet trager?

Visit my new Blog!
www.Snowball.be


  • whoami
  • Registratie: December 2000
  • Laatst online: 21-05 23:34
gill schreef op 07 oktober 2004 @ 09:49:
[...]


Maar wordt de code niet logger hierdoor? Zoveel geneste blokken edm, maakt dat de executie niet trager?
Indirect wel; zie m'n vorige voorbeeld:
stel, de allocatie van de dataset faalt, er wordt een exceptie gegooid, die wordt opgevangen, het programma springt naar de volgende lijn code na het catch-blok, de data-adapter probeert de dataset te vullen, maar die dataset is er niet want hij kon niet gecreeërd worden: er wordt een exceptie gegooid (wat duur is), er wordt naar de catch gegaan, en er wordt opnieuw naar de eerstvolgende lijn code na het catch-blok gegaan ....
Dus, ipv 1 duidelijke foutmelding, krijg je gewoon een rits van excepties voor je neus. Lekker voor de gebruiker...

https://fgheysels.github.io/


  • gill
  • Registratie: Januari 2002
  • Laatst online: 26-12-2025

gill

Love my lindsey...

Topicstarter
Nice... het ligt dus niet aan mijn programmeerstijl :)

Visit my new Blog!
www.Snowball.be


  • pjvandesande
  • Registratie: Maart 2004
  • Laatst online: 21-05 14:59

pjvandesande

GC.Collect(head);

Kijk ook is naar finally, als er iets mis is gegaan, dus een exception is opgetreden kun je daar je unmanaged resources bijvoorbeeld weer opruimen.

Het finally -blok word altijd uitgevoerd.

Maar om op jou vraag antwoord te geven, kijk in de refence (MSDN) welke method welke exceptions kan gooien. Deze zijn slim om af te vangen, maar het is onzin om elke regel in een try -catch te zetten.

Dit het ik ook wel is gezien... geloof mij, heel erg vervelend om voor op je bord geworpen te krijgen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public int CountRow()
{
    try
    {
        int retVal = -1;
    }
    catch
    {
        // Exception handling
    }

    try
    {
        SqlConnection dbConn = new SqlConnection("connstr");
        _cmdCount.Connection = dbconn;
    }
    catch
    {
        // Exception handling
    }
    
    try
    {
        SqlDataReader reader = _cmdCount.ExecuteReader();

        if(reader.Read)
            retVal = reader.GetInt(0);
    }
    catch
    {
        // Exception handling
    }

    return retVal;
}


Je kan natuurlijk alles samenvoegen tot 1 blok, en zoals whoami al zegt, een blok kan meerderen try -catch blokken bevatten. Je kan ze dus nesten.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public int CountRow()
{
    int retVal = -1;

    try
    {
        SqlConnection dbConn = new SqlConnection("connstr");
        _cmdCount.Connection = dbconn;

        SqlDataReader reader = _cmdCount.ExecuteReader();

        if(reader.Read)
            retVal = reader.GetInt(0);
    }
    catch
    {
        // Exception handling
    }
    finally
    {
        if(dbConn != null)
            dbConn.Close();
    }

    return retVal;
}


edit:

Zo lang getypt in notepad, geen VS hier... en ik post is whoami me al weer voor!
:7

[ Voor 5% gewijzigd door pjvandesande op 07-10-2004 09:59 ]


  • Sjaaky
  • Registratie: Oktober 2000
  • Laatst online: 22-04 07:04
Als je om elke regel code een try/catch blok gaat maken bereik je hetzelfde als dat je van elke functie de returncode gaat checken. Je bent imho terug bij af. Exceptions zijn juist bedacht om te voorkomen dat je onoverzichtelijke code moet schrijven om de returncodes te checken. Het uitgangspunt hierbij is dat code die niet vaak wordt uitgevoerd (het is immers een foutconditie) niet zo dominant aanwezig moet zijn in je code.
Ik zie trouwens dat je projectleider zegt dat elke lijn in een try/catch blok moet staan, maar niet dat om elk statement een apart try/catch blok moet staan. Wat dat betreft heeft hij wel gelijk, elke mogelijke exceptie zou opgevangen moeten worden door je eigen exceptionhandler. Dat hoeft dan niet binnen dezelfde methode te zijn oid. Maar elke exceptie moet uiteindelijk gevangen worden. Het voordeel van excepties boven returncodes is dat excepties 'door de callstack terug naar boven' propageren. Hierdoor kan je elke verschillende fout afhandelen in de methode die er het beste voor geschikt is, zonder dat je er druk over te hoeven maken in andere methoden.

  • MrSleeves
  • Registratie: Februari 2004
  • Laatst online: 10-04 19:23

MrSleeves

You'll thank me later.

Persoonlijk ben ik best zuinig met Try-Catch-blokken. Als ik ze gebruik staan ze echt niet om de regel of genest. Dat slaat namelijk nergens op.

Als een Hide-functie kan crashen, dan crashtie maar. Als daar al een Exception van komt, dan is het maar de vraag of je die af kan vangen met een Catch.
Ik denk het namelijk niet, want een grote kans dat het deze is, de moeder aller Exceptions.

Maargoed, je kan beter zelf een Try-Catch blok doen over de hele applicatie om domme fouten op te vangen en verder gewoon proberen dingen te checken, i.p.v. te proberen met wéér een Try-Catch.
Controleren op IsNull (datasets) i.p.v. proberen en kijken ofie met een Exception komt (gaat ook sneller, want die Excpetions vertragen de boel wel als ze gegooid worden).

30Drie Web Design & IT Consultancy | Raven Consultancy Services


  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Je moet alleen een exception catchen als je er ook iets nuttigs mee gaat doen. Als je control crashed omdar er geen geheugen is om een scrollbar aan te maken; wat ga je daar dan aan doen? Als je idd die exception op kan vangen, om een controll met minder geheugen gebruik aan te maken, dan is het prima. Anders kan je beter de exception laten lopen en hopen dat op een hoger niveau er iets mee gedaan wordt. Misschien wordt je sub programma afgesloten, en geheugen vrijgemaakt, waarna je het opnieuw kan proberen.

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 21-05 23:07
Ik vind het zelf alleen zinnig om (ten eerste) exceptions te catchen die daadwerkelijk gegooid worden (duh) en/of waarvan je verwacht dat ze ook zullen optreden (dus niet: deling door nul of element niet gevonden afvangen, als je weet dat die situaties niet voor kunnen komen). Verder heeft het alleen zin om exceptions te catchen die je ook daadwerkelijk kunt en gaat afhandelen.

Zelf negeer ik exceptions voor dingen als geheugengebrek bijna altijd; ik probeer ze in ieder geval nooit ter plekke op te lossen. Dat komt omdat de situatie redelijk zeldzaam is, praktisch overal kan voorkomen en bovendien meestal niet redelijkerwijs op te lossen is zonder de huidige functie af te breken. In sommige situaties handel ik dat soort exceptions nog wel op globaal nivo af (en in een aantal specifieke functies die echt atomair uitgevoerd moeten worden) zodat bij het afsluiten databases consistent zijn en instellingen wel bewaard blijven. Dan is er vooral spraken van de schade beperken en niet zozeer van het afhandelen van een specifieke exception; de procedure is namelijk hetzelfde voor een andere onvoorspelbare exception als een deling door nul.

Het is sowieso wel prettig dat exceptions niet verborgen worden en dus 'ergens' afgehandeld worden. In C++ gebeurt dat doordat de applicatie netjes crasht als een exception niet afgevangen wordt en in Java wordt de exception naar de console geprint; ik denk dat VB.Net dat ook doet. Echt heel nuttig is dat niet, want de exception wordt dan zelf niet verwerkt. Het is dus niet onredelijk dat de projectleider verwacht dat alle relevante exceptions ook afgehandeld worden, maar het lijkt mij dat het niet uitmaakt waar dat precies gebeurt; als het goed kan, kan dat ook veel hoger in de code dan direct na de regel code die de exception veroorzaakt.
Pagina: 1