Autor Beitrag
iwb-augsburg
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mi 28.11.07 10:33 
Hallo ich greife auf eine Access-Datenbank in einer do-while-Schleife pausenlos zu. Leider führt daran kein weg vorbei, denn die Datenbank stellt eine Schnittstelle dar, die permanent abgefragt werden muss.
Leider kommt es nach 6 Sekunden (das sind ca 650 Zugriffe, weil ich System.Threading.Thread.Sleep(10); benutze) zu einer Exception, die aus meiner Sicht vom Betriebssystem (bei mir Windows XP Prof) verursacht wird:
Diese lautet:
Eine nicht behandelte Ausnahme des Typs "System.Data.OleDb.OleDbException" ist in System.Data.dll aufgetreten.
Zusätzliche Informationen: Zusätzliche Tabellen können nicht geöffnet werden.


Der Fehler wird hier verursacht: "MyDataReader = cmd.ExecuteReader();"

Wie kann ich dieses Problem umgehen? Bitte beachtet, dass ich diesen permanenten Zugriff auf die Datenbank unbedingt brauche.

Vielen Dank


ausblenden volle Höhe C#-Quelltext
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:
36:
37:
38:
39:
using System;                                                                           // Standard
using System.Collections.Generic;                                                       // Standard
using System.Data.OleDb;                                                                // für die Datenbank
using System.Data.SqlClient;                                                            // für die Datenbank
using System.Text;                                                                      // Standard

namespace CoCo
{
    class Get_CosimirReturnValues
    {
        // Variablen
        private OleDbCommand cmd;
        private OleDbDataReader MyDataReader;
        private string check_return_value = "SELECT return_values FROM CosimirPrograms WHERE programNr = ";
        public string return_value;




        // Prüft ob Cosimir einen Rückgabewert geliefert hat und gibt diesen zurück: Tabelle "CosimirPrograms", die Zeile entspricht der übergebenen Programmnummer, solange bis Wert ungleich NULL
        public string get_return_values(string cosimirProgramNr, OleDbConnection con)
        {

            //string values = check_return_value + cosimirProgramNr;
            do
            {
                cmd = new OleDbCommand(check_return_value + cosimirProgramNr, con);
                MyDataReader = cmd.ExecuteReader();
                MyDataReader.Read();
                return_value = MyDataReader["return_values"].ToString();                // muss in dieser Form gar nicht sein, denn C# erkennt den Ihnhalt auch ohne Stringkonvertierung
                System.Threading.Thread.Sleep(10);                                      // Sehr wichtig für Ressourcenfreigabe, ohne 25% mit 3%
            }
            while (return_value == "");

            return return_value;
        }
        // ENDE - "class Get_CosimirReturnValues"
    }
}



Moderiert von user profile iconChristian S.: Topic aus C# - Die Sprache verschoben am Mi 28.11.2007 um 09:38
Moderiert von user profile iconChristian S.: Code- durch C#-Tags ersetzt
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mi 28.11.07 11:17 
Versuche es einmal damit, den DbCommand nur einmal zu erzeugen und für jeden neuen Aufruf den CommandText anzupassen.

Meine Idee dahinter: Für jeden neuen DbCommand wird ein neuer DbDataReader erzeugt; der GC hat keine Zeit zum Aufräumen; das Betriebssystem wird dann durch "zu viele" DataReader überfordert.

Gruß Jürgen
iwb-augsburg Threadstarter
Hält's aus hier
Beiträge: 6



BeitragVerfasst: Mi 28.11.07 11:36 
Hallo Jürgen, das scheint nicht zu funktionieren.
Aber mir wurde gerade ein Lösung "zugeflüstert", die mein Problem aus der Welt schafft.

MyDataReader.Close();

Verhindert, dass zu viele Tabellen geöffnet werden, die zu dieser Exception führen.
Das Programm "hängt" zwar, bis es die werte kriegt aber es funktioniert.


@ Jürgen: du bist ja in jedem C# Forum zuhause ;) Danke vielmals
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mi 28.11.07 12:11 
user profile iconiwb-augsburg hat folgendes geschrieben:
Hallo Jürgen, das scheint nicht zu funktionieren.
Aber mir wurde gerade ein Lösung "zugeflüstert", die mein Problem aus der Welt schafft.

MyDataReader.Close();

In der Tat, so steht es auch für jeden DataReader in der SDK-Doku:
Zitat:
Während der Verwendung des OleDbDataReader ist die zugeordnete OleDbConnection durch den Informationsfluss für den OleDbDataReader belegt, sodass an der OleDbConnection keine anderen Operationen ausgeführt werden können, außer diese zu schließen. Dies gilt solange, bis die Close-Methode von OleDbDataReader aufgerufen wird.

Ich habe das übersehen, weil ich bisher zu selten damit gearbeitet habe.
user profile iconiwb-augsburg hat folgendes geschrieben:
Verhindert, dass zu viele Tabellen geöffnet werden, die zu dieser Exception führen.
Das Programm "hängt" zwar, bis es die werte kriegt aber es funktioniert.

Das "Hängen" wird ja auch von Dir durch Sleep() verursacht.
user profile iconiwb-augsburg hat folgendes geschrieben:
@ Jürgen: du bist ja in jedem C# Forum zuhause ;) Danke vielmals

In jedem? Weiß nicht. Aber deshalb ärgere ich mich auch, wenn ich eine Frage in jedem Forum lese und die Helfer nichts voneinander wissen. Jürgen
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Mi 28.11.07 18:18 
DbDataReader implementiert IDisposable, also ist eine Nutzung eines using-Blocks das einzig Vernünftige. Denn ich wette, auch in deiner nun vermeintlich richtigen Version fehlt der finally-Block ;) . Am liebsten wäre es mir, wenn die ganzen Close-Methoden als obsolet markeiert und IDEs disposable Types speziell highlighten würden (ich stimme für violett oder braun ^^ ).