Finally block met connection.Close() uit andere klasse

Pagina: 1
Acties:

Onderwerpen

Vraag


  • DutchDeafBoy
  • Registratie: Augustus 2014
  • Laatst online: 11-09-2024
Ik ben momenteel bezig met het schrijven van een programma dat een koppeling maakt met een database. Hierbij gebruik ik try-catch-finally om exceptions af te handelen. Het probleem: de handling gebeurt in de Form-klasse, terwijl de connectie met de database in een andere klasse gebeurt.

Ik wil dat als de exception voorkomt de verbinding gesloten wordt. Met connection.Close(). Alleen heb ik geen idee hoe ik dat vanuit een andere klasse doe. Kan iemand mij dit vertellen?

Ter info: ik weet wel hoe je een koppeling tussen twee klassen maakt. Ik ging ervan uit dat het met connection.Close() wel (grotendeels) hetzelfde zou werken, maar dat bleek dus niet zo. Wellicht zie ik hierbij iets over het hoofd?


Voor de goede orde even de betreffende code uit de Form1-klasse:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
try
            {
                Database db1 = new Database();
                lblAantal.Text = db1.GetCount().ToString();

                Database db2 = new Database();
                lblAantalDB.Text = db2.GetCountDB().ToString();
            }
            catch (SqlException)
            {
                MessageBox.Show("Er kan geen verbinding worden gemaakt met de database", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                
            }

[ Voor 30% gewijzigd door DutchDeafBoy op 21-12-2017 18:52 ]

LG OLED55C9PLA | iPhone 15 Pro Max | 11-inch iPad Pro (2024) | Apple Watch Series 10

Beste antwoord (via DutchDeafBoy op 21-12-2017 20:18)


  • Mschamp
  • Registratie: April 2014
  • Laatst online: 07:02
Is het niet mogelijk om naast je huidige try Catch Finally, nog een extra te programmeren in je database klasse?

In je database van je dan je fout op, in je finally sluit je je verbinding, en je Throwt je error opnieuw, zodat de bovenliggende klasse op de hoogte is van de error.

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
Database:
  Try {
        Conn.open()  //open verbinding
        haal data op
  }
  Catch (SqlException) {
           throw SqlException   //zodat je error doorgegeven wordt naar boven
   }
  Finally {
            Conn.Close()  //Verbinding sluiten 
   }


Form-klasse:
     try
            {
                Database db1 = new Database();
                lblAantal.Text = db1.GetCount().ToString();

                Database db2 = new Database();
                lblAantalDB.Text = db2.GetCountDB().ToString();
            }
            catch (SqlException)
            {
                MessageBox.Show("Er kan geen verbinding worden gemaakt met de database", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


De Finally in je form klasse lijkt dan ook overbodig te zijn (met dit beperkt stukje code, kan mogelijk in je toepassing wel nog een doel hebben).

Alle reacties


  • DRvDijk
  • Registratie: Juni 2001
  • Laatst online: 01-09 11:48
Bedoel je een .Close() aanroep te doen op db1 of db2? Want daar kan je met je huidige code inderdaad niet bij zo te zien (niet helemaal zeker van de tala die je gebruikt). Maar misschien kun je de instanties wel buiten de try block declareren, in de try initialiseren en gebruiken, en in de finally block checken op null. Zoiets:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Database db1 = null;
Database db2 = null;
try
            {
                db1 = new Database();
                lblAantal.Text = db1.GetCount().ToString();

                db2 = new Database();
                lblAantalDB.Text = db2.GetCountDB().ToString();
            }
            catch (SqlException)
            {
                MessageBox.Show("Er kan geen verbinding worden gemaakt met de database", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (db1 != null) {
                  db1.Close();
                }
                if (db2 != null) {
                  db2.Close();
                }
            }



hth

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Wat doet die Database class eigenlijk ?
En wanneer wordt de connectie precies geopend ?

Zowiezo vind ik het geen goed idee dat de consumer van die Database class niet zelf aangeeft wanneer de connectie moet geopend worden.

https://fgheysels.github.io/


  • DutchDeafBoy
  • Registratie: Augustus 2014
  • Laatst online: 11-09-2024
DRvDijk schreef op donderdag 21 december 2017 @ 19:40:
Bedoel je een .Close() aanroep te doen op db1 of db2? Want daar kan je met je huidige code inderdaad niet bij zo te zien (niet helemaal zeker van de tala die je gebruikt). Maar misschien kun je de instanties wel buiten de try block declareren, in de try initialiseren en gebruiken, en in de finally block checken op null. Zoiets:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Database db1 = null;
Database db2 = null;
try
            {
                db1 = new Database();
                lblAantal.Text = db1.GetCount().ToString();

                db2 = new Database();
                lblAantalDB.Text = db2.GetCountDB().ToString();
            }
            catch (SqlException)
            {
                MessageBox.Show("Er kan geen verbinding worden gemaakt met de database", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                if (db1 != null) {
                  db1.Close();
                }
                if (db2 != null) {
                  db2.Close();
                }
            }



hth
Dat levert een exception op, hij herkent .Close() niet dan. :P
whoami schreef op donderdag 21 december 2017 @ 19:44:
Wat doet die Database class eigenlijk ?
En wanneer wordt de connectie precies geopend ?

Zowiezo vind ik het geen goed idee dat de consumer van die Database class niet zelf aangeeft wanneer de connectie moet geopend worden.
Dit is de methode van één van de twee (tweede is grotendeels hetzelfde, voornaamste verschil is de query):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public int GetCount()
        {
            string query2 = "SELECT COUNT(instelling_id) FROM opleidingsinstellingen;";

            // database connection
            connection.Open();

            // sql command
            SqlCommand cmd2 = new SqlCommand(query2, connection);

            // execute command
            Int32 count = (Int32)cmd2.ExecuteScalar();

            string display = count.ToString();
            
            // return result
            return (int) count;

        }

LG OLED55C9PLA | iPhone 15 Pro Max | 11-inch iPad Pro (2024) | Apple Watch Series 10


Acties:
  • Beste antwoord
  • 0 Henk 'm!

  • Mschamp
  • Registratie: April 2014
  • Laatst online: 07:02
Is het niet mogelijk om naast je huidige try Catch Finally, nog een extra te programmeren in je database klasse?

In je database van je dan je fout op, in je finally sluit je je verbinding, en je Throwt je error opnieuw, zodat de bovenliggende klasse op de hoogte is van de error.

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
Database:
  Try {
        Conn.open()  //open verbinding
        haal data op
  }
  Catch (SqlException) {
           throw SqlException   //zodat je error doorgegeven wordt naar boven
   }
  Finally {
            Conn.Close()  //Verbinding sluiten 
   }


Form-klasse:
     try
            {
                Database db1 = new Database();
                lblAantal.Text = db1.GetCount().ToString();

                Database db2 = new Database();
                lblAantalDB.Text = db2.GetCountDB().ToString();
            }
            catch (SqlException)
            {
                MessageBox.Show("Er kan geen verbinding worden gemaakt met de database", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


De Finally in je form klasse lijkt dan ook overbodig te zijn (met dit beperkt stukje code, kan mogelijk in je toepassing wel nog een doel hebben).

  • DutchDeafBoy
  • Registratie: Augustus 2014
  • Laatst online: 11-09-2024
Dat werkt inderdaad wel prima! Dank voor de hulp, waardeer dat zeer. :)

LG OLED55C9PLA | iPhone 15 Pro Max | 11-inch iPad Pro (2024) | Apple Watch Series 10


Acties:
  • 0 Henk 'm!

  • P_Tingen
  • Registratie: Maart 2005
  • Laatst online: 17-09 12:52

P_Tingen

omdat het KAN

Volgens mij zou je uberhaupt dit soort dingen niet moeten mengen. Als klasse B verantwoordelijk is voor het openen van de verbinding, dan moet hij ook verantwoordelijk zijn voor het sluiten, een variant op: "you create it, you delete it"

... en gaat over tot de orde van de dag


Acties:
  • 0 Henk 'm!

  • jmzeeman
  • Registratie: April 2007
  • Laatst online: 12-09 16:17
Mschamp schreef op donderdag 21 december 2017 @ 19:59:
Is het niet mogelijk om naast je huidige try Catch Finally, nog een extra te programmeren in je database klasse?

In je database van je dan je fout op, in je finally sluit je je verbinding, en je Throwt je error opnieuw, zodat de bovenliggende klasse op de hoogte is van de error.

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
Database:
  Try {
        Conn.open()  //open verbinding
        haal data op
  }
  Catch (SqlException) {
           throw SqlException   //zodat je error doorgegeven wordt naar boven
   }
  Finally {
            Conn.Close()  //Verbinding sluiten 
   }


Form-klasse:
     try
            {
                Database db1 = new Database();
                lblAantal.Text = db1.GetCount().ToString();

                Database db2 = new Database();
                lblAantalDB.Text = db2.GetCountDB().ToString();
            }
            catch (SqlException)
            {
                MessageBox.Show("Er kan geen verbinding worden gemaakt met de database", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


De Finally in je form klasse lijkt dan ook overbodig te zijn (met dit beperkt stukje code, kan mogelijk in je toepassing wel nog een doel hebben).
Je hoeft in de database natuurlijk geen catch te doen alleen om hem meteen weer te gooien je hoeft daar alleen try en finally te gebruiken dus:
code:
1
2
3
4
5
6
7
8
9
10
Database:
  try 
  {
        Conn.open()  //open verbinding
        haal data op
  }
  finally 
  {
        Conn.Close()  //Verbinding sluiten 
  }

Acties:
  • 0 Henk 'm!

  • Tweezitsbank
  • Registratie: December 2016
  • Niet online

Tweezitsbank

Relax...

Mschamp schreef op donderdag 21 december 2017 @ 19:59:
In je database van je dan je fout op, in je finally sluit je je verbinding, en je Throwt je error opnieuw, zodat de bovenliggende klasse op de hoogte is van de error.

code:
1
2
3
4
5
  }
  Catch (SqlException) {
           throw SqlException   //zodat je error doorgegeven wordt naar boven
   }
  Finally {
De correcte manier om een exception te rethrowen is:
code:
1
2
3
4
5
6
7
8
try
{
  ...
}
catch (SqlException ex)
{
   throw;
}


Je raakt op deze manier de call stack niet kwijt. Waar dit precies in de MS docs staat weet ik even niet, maar bijvoorbeeld wel hier:
https://stackoverflow.com...e-throw-an-exception-in-c
Pagina: 1