Guten Morgen zusammen,
ich beschäftige mich im Laufe eines kleinen Projektes gerade mit Threading.
Das Projekt an sich soll so etwas wie ein DashBoard sein. Es sollen also möglichst aktuelle Daten dargestellt werden. Dazu habe ich für jeden relevanten Wert eine Datenbank Abfrage, die nach und nach durchgegangen wird und dann das entsprechende Label füllt.
Bei wenigen Labels ging alles noch sehr flott. Nun hat man natürlich immer mehr Ideen was relevant sein könnte und möchte dieses darstellen. Aktuell 28 Labels die auch gefüllt werden wollen...
Das Füllen der Labels habe ich bisher so gelöst: In meiner Methode datenFüllen() wird dem Label der Wert der Abfrage zugewiesen. Alles nach diesem System:
Methode um das Label zu beschrieben:
Ich habe einen Aufruf von datenFüllen() im Form Load und dann im Timer, der alle 30 Sekunden die Daten aktualisieren soll.
Durch die Reihe an Abfragen, die durch das datenFüllen() im Load ausgeführt werden, dauert es natürlich bis die User Form aufgebaut ist. Auch friert die Form durch das Aufrufen von datenFüllen() im Timer immer ein.
Durch den Einsatz von Threads wollte ich das Einfrieren und die lange Aufbauzeit verhindern. Dazu habe ich mir gedacht, dass ich die 28 Abfragen auf 5 Threads aufteile.
Die Verbindung zur Datenbank stelle ich auch in Form Load her.
Nun habe ich das Problem, dass jedes setLabelTxt natürlich eine Datenbank Abfrage ausführen möchte. Da es nun vor kommt, dass myConn.Open() von unterschiedlichen Threads gleichzeitig versucht wird aufzurufen, kommt es natürlich zu einem Fehler.
Setzte ich alle Abfragen für das Label in einen Thread klappt auch fast alles. Die Form friert nicht mehr ein, es dauert aber trotzdem noch recht lange.
Soweit sehr viel mehr Text als gedacht bis hierhin
Meine eigentlichen Fragen:
Wie kann ich es so programmieren, dass es zu keinem Fehler durch die mehrfach Verwendung meiner Connection gibt?
Kann ich dazu die Datenbank Abfrage in den Thread irgendwie auslagern?
Müsste ich dazu zu jeden Thread die Datenbankverbindung neu öffnen?
Falls mein oben dargestelltes Vorgehen eventuell noch zu verbessern wäre, bitte ich gerne um Vorschläge
Vielen Dank für eure Hilfe!
Grüße Jan
ich beschäftige mich im Laufe eines kleinen Projektes gerade mit Threading.
Das Projekt an sich soll so etwas wie ein DashBoard sein. Es sollen also möglichst aktuelle Daten dargestellt werden. Dazu habe ich für jeden relevanten Wert eine Datenbank Abfrage, die nach und nach durchgegangen wird und dann das entsprechende Label füllt.
Bei wenigen Labels ging alles noch sehr flott. Nun hat man natürlich immer mehr Ideen was relevant sein könnte und möchte dieses darstellen. Aktuell 28 Labels die auch gefüllt werden wollen...
Das Füllen der Labels habe ich bisher so gelöst: In meiner Methode datenFüllen() wird dem Label der Wert der Abfrage zugewiesen. Alles nach diesem System:
Methode um das Label zu beschrieben:
Quellcode
Ich habe einen Aufruf von datenFüllen() im Form Load und dann im Timer, der alle 30 Sekunden die Daten aktualisieren soll.
Durch die Reihe an Abfragen, die durch das datenFüllen() im Load ausgeführt werden, dauert es natürlich bis die User Form aufgebaut ist. Auch friert die Form durch das Aufrufen von datenFüllen() im Timer immer ein.
Durch den Einsatz von Threads wollte ich das Einfrieren und die lange Aufbauzeit verhindern. Dazu habe ich mir gedacht, dass ich die 28 Abfragen auf 5 Threads aufteile.
Quellcode
- Private Sub datenFüllenÜbersicht()
- '### Übersicht ###
- setLabelTxt(returnWert(My.Settings.sqlOffenePicksWoche), lblOffenePicksWoche)
- setLabelTxt(returnWert(My.Settings.sqlPicksMin), lblPicksMin)
- setLabelTxt(returnWert(My.Settings.sqlPicksMinHeute), lblPicksMinHeute)
- setLabelTxt(returnWert(My.Settings.sqlPicksMinGestern), lblPicksMinGestern)
- setDataSource(returnDataTable(My.Settings.sqlKomOffeneAufgaben), dgvKomOffeneAufgaben) 'Ganzes DataTable an DataGridView übergeben
- End Sub
Quellcode
- Public Function returnWert(strSQL As String) As String
- Dim strReturn As String
- Dim myDataTable As DataTable
- myDataTable = SQL.abfragenStarten(strSQL)
- If myDataTable.Columns.Count > 0 Then
- 'Daten vorhanden
- strReturn = myDataTable.Rows(0)(0).ToString()
- Else
- 'Keine Daten vorhanden
- strReturn = ""
- End If
- Return strReturn
- End Function
Quellcode
- Public Function abfragenStarten(strSQL As String) As DataTable
- 'Führt die SQL Abfrage aus und gibt das Ergebnis als DataReader zurück.
- Dim dtDataTable As New DataTable
- If strSQL = "" Then
- 'keine Abfrage vorhanden: Lasse leeren DatTable returnen.
- Else
- 'Create a Command object.
- myCmd = myConn.CreateCommand
- myCmd.CommandText = strSQL
- 'Open the connection.
- myConn.Open()
- Dim drDaten As SqlDataReader
- drDaten = myCmd.ExecuteReader()
- dtDataTable.Load(drDaten)
- SQL.myConn.Close() 'Nachdem die Abfragewerte genutzt wurden, die Verbindung beenden.
- End If
- Return dtDataTable
- End Function
Die Verbindung zur Datenbank stelle ich auch in Form Load her.
Nun habe ich das Problem, dass jedes setLabelTxt natürlich eine Datenbank Abfrage ausführen möchte. Da es nun vor kommt, dass myConn.Open() von unterschiedlichen Threads gleichzeitig versucht wird aufzurufen, kommt es natürlich zu einem Fehler.
Setzte ich alle Abfragen für das Label in einen Thread klappt auch fast alles. Die Form friert nicht mehr ein, es dauert aber trotzdem noch recht lange.
Soweit sehr viel mehr Text als gedacht bis hierhin
Meine eigentlichen Fragen:
Wie kann ich es so programmieren, dass es zu keinem Fehler durch die mehrfach Verwendung meiner Connection gibt?
Kann ich dazu die Datenbank Abfrage in den Thread irgendwie auslagern?
Müsste ich dazu zu jeden Thread die Datenbankverbindung neu öffnen?
Falls mein oben dargestelltes Vorgehen eventuell noch zu verbessern wäre, bitte ich gerne um Vorschläge
Vielen Dank für eure Hilfe!
Grüße Jan