[C# ADO.Net]Probleem met connecties

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • FoOnEeN
  • Registratie: Juli 2003
  • Laatst online: 15-09 21:20
Ik heb een probleem met een stukje code dat een query uitvoert. Het lijkt namelijk dat om de een of andere reden deze de connectie niet goed sluit, waardoor ik foutmeldingen krijg. Het typische eraan is dat dit ook meerdere verschillende foutmeldingen zijn, zie hieronder:
  • There is already an open DataReader associated with this Command which must be closed first
  • ExecuteReader requires an open and available Connection. The connection's current state is closed.
  • Invalid attempt to call HasRows when reader is closed
Allemaal zijn het heel logische foutmeldingen die mij normaal zouden wijzen op het niet aanroepen van .Close() op een reader of connectie, echter doe ik dat wel. Hieronder het probleemvolle stuk code:

[code=C#]
public Object GetInfo()
{
Object blaat = null;

try
{
//Construct the command object with its parameters
SqlCommand cmd = new SqlCommand(//Query, dbConnectie);
cmd.CommandType = CommandType.Text;

//parameters;

//Open the connection if not already open (Somewhere in the code this connection is not closed)
//Tijdelijke test aangezien de eerste fout over deze regel ging
if (!(dbConnectie.State == dbConnectie.Open))
dbConnectie.Open();

SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.SingleResult);

//Check if object is null
if (reader != null)
{
//Check if any rows are returned
if (reader.HasRows)
{
//Get the record and create an object from it, save the data in the object
while (reader.Read())
{
// populatie variabelen object
}
}

//Close the object
reader.Close();
}

//Close connection
dbConnectie.Close();
}
catch (Exception ex)
{
//Log error
}
finally
{
if (dbConnectie.State == dbConnectie.Open)
{
//Close connection
dbConnectie.Close();
}
}

return blaat;
}
[/code=C#]

Toch triggeren de verschillende foutmeldingen op regels 17 en 23, wat logisch is. Probleem is nu dat de foutmeldingen random optreden, en niet echt terug te traceren zijn naar 1 proces of ander iets. In 99% van de tijd krijg ik nergens problemen, toch op sommige momenten krijg ik dit terug.

Ik dacht eerst dat het bovenliggende proces de connectie niet sluit voordat hij dit uitvoert, echter heb ik dat gefixt, toen gebeurde het wel minder vaak maar nog steeds.
Ik heb nog steeds het vermoeden dat er ergens iets mis gaat met het niet sluiten van de connectie in mijn andere code, alleen heb ik dat nog niet kunnen vinden.

Heeft iemand een ander idee wbt het optreden van deze foutmeldingen?


EDIT:
Dat die fout optreed tussen regel 18 en 34 kan niet aangezien ik dit dan in de error logging zou moeten terugzien.

En de connectie instantie die ik hier gebruik is een klasse variabele, die 3 functies bevat die deze connectie gebruiken. Deze andere 2 functies worden echter niet aangeroepen in dit proces, en deze handelen verder ook alles goed af.

Ik zat zelf overigens ook al te denken aan het aanmaken van een nieuw connectie object, echter creëert dit niet teveel performanceverlies?

[ Voor 64% gewijzigd door FoOnEeN op 05-11-2009 12:15 . Reden: Iets te vroeg op verstuur geramt ]


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Ben je zeker dat er nooit een exceptie optreedt tussen regel 18 & regel 34 ? Dat zal er nl. toe leiden dat je reader nooit gesloten wordt.

Zowiezo vind ik het ook vreemd (en gevaarlijk) dat je blijkbaar altijd met dezelfde connection instance werkt.
Waarom doe je dat ?
En ook: blijkbaar is het mogelijk dat je in bovenstaande functie reeds met een connectie te maken krijgt, die reeds geopend is. Echter, waarom ga je in die gevallen dan ook de connectie opnieuw gaan sluiten ? (want je sluit je connectie wel altijd). Als je connectie open is, dan lijkt het me dat een ander proces/method deze connectie kan geopend hebben, en dan verwacht dat ander proces waarschijnlijk niet dat zijn connectie opnieuw kan gesloten zijn.

Dus, waarom niet een nieuwe connection-instance maken ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

Is die dbconnectie member static? Zoja dan kan dat weleens je probleem zijn. Of wordt de instance op een andere manier op meerdere plaatsen tegelijk gebruikt.

Om te switchen van state gebruik ik zelf trouwens de volgende code

C#:
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
        public static void SwitchConnectionState(IDbConnection conn, ConnectionState newstate)
        {
            switch (conn.State)
            {
                case ConnectionState.Broken:
                    if (newstate == ConnectionState.Closed)
                    {
                        conn.Close();
                    }
                    else if (newstate == ConnectionState.Open)
                    {
                        conn.Close();
                        conn.Open();
                    }
                    break;
                case ConnectionState.Closed:
                    if (newstate == ConnectionState.Open)
                    {
                        conn.Open();
                    }
                    break;
                case ConnectionState.Open:
                    if (newstate == ConnectionState.Closed)
                    {
                        conn.Close();
                    }
                    break;
                default:
                    throw new Exception("Connection is in an unknown state.");
            }
        }

[ Voor 93% gewijzigd door Brakkie op 05-11-2009 13:27 ]

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • BM
  • Registratie: September 2001
  • Laatst online: 20:37

BM

Moderator Spielerij
Weet je zeker dat die Close op je connectie ook daadwerkelijk uitgevoerd word?

Wat als je er zoiets van maakt:

C#:
1
2
3
4
5
if (dbConnectie.State != dbConnectie.Closed)
{
  //Close connection
  dbConnectie.Close();
} 


Zal vast een stomme oplossing zijn, maar is het 1e wat me zo te binnen schiet.

Xbox
Even the dark has a silver lining | I'm all you can imagine times infinity, times three


Acties:
  • 0 Henk 'm!

  • FoOnEeN
  • Registratie: Juli 2003
  • Laatst online: 15-09 21:20
Hmm mijn connectie variabele is idd static, echter is hij dat wel op meerdere plekken. Ik zal het eens veranderen en kijken of dat mijn probleem oplost.

Echter is het zo dat dit dus in 99% van de tijd geen problemen oplevert. Ook in mijn testomgeving merk ik hier helemaal niets van. Wat is de reden dat dit object niet static zou mogen zijn?

Acties:
  • 0 Henk 'm!

  • Brakkie
  • Registratie: Maart 2001
  • Niet online

Brakkie

blaat

FoOnEeN schreef op donderdag 05 november 2009 @ 13:27:
Hmm mijn connectie variabele is idd static, echter is hij dat wel op meerdere plekken. Ik zal het eens veranderen en kijken of dat mijn probleem oplost.

Echter is het zo dat dit dus in 99% van de tijd geen problemen oplevert. Ook in mijn testomgeving merk ik hier helemaal niets van. Wat is de reden dat dit object niet static zou mogen zijn?
Een static variabele wordt eenmalig geinstantieerd voor een applicatie domein. Wanneer binnen dit applicatie domein de state van de connectie gewijzigd wordt naar open en een andere thread zet de connectie state gelijk weer naar closed heb je een probleem binnen de eerste thread.

Een verhaal over statics binnen de asp.net context

Systeem | Strava


Acties:
  • 0 Henk 'm!

  • FoOnEeN
  • Registratie: Juli 2003
  • Laatst online: 15-09 21:20
Aha ik had al zo'n idee dat het iets met threads te maken had, aangezien de foutmeldingen op verschillende plekken voorkomen. Dit correspondeert dus met verschillende threads die op verschillende plekken in de uitvoer zijn. Ik kan niet direct testen of dit het probleem oplost, maar als dit wel zo is, zeer bedankt :),

Acties:
  • 0 Henk 'm!

  • D-Raven
  • Registratie: November 2001
  • Laatst online: 10-09 20:32
Even terzijde. In plaats van die hele if banaan kan je ook je SqlDataReader wrappen in het using statement.

C#:
1
2
3
4
5
6
7
8
9
10
using (var reader = cmd.ExecuteReader(CommandBehavior.SingleResult))
            {
                if (reader.HasRows) //<-- hoeft niet, reader.read() returned gewoon false als er geen rows inzitten
                {
                    while (reader.Read())
                    {
                        // populatie variabelen object
                    }
                }
            }


Aan het einde van de using word de reader geclosed, gedisposed en onderliggende resources opgeruimd.
Pagina: 1