Funktion mit Datatable als Rückgabewert -> Arbeitsspeicher frei geben

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Funktion mit Datatable als Rückgabewert -> Arbeitsspeicher frei geben

    Halihallo :)

    Sagen wir mal ich habe eine Funktion:

    VB.NET-Quellcode

    1. Public Function XYZ() As DataTable
    2. Dim dt as Datatable
    3. dt = blabla ' Hier wird halt das Datatable befüllt
    4. Return dt
    5. End Function


    Damit habe ich ja sämtliche Daten die ich in "dt" geladen habe. Auch im Arbeitsspeicher.

    Wie kann ich diesen Arbeitsspeicher denn nun wieder frei geben?

    Sagen wir mal ich mache:

    VB.NET-Quellcode

    1. Datagridview1.Datasource = XYZ()


    Vermutlich muss ich irgendwo .Dispose aufrufen aber ich weiss leider nicht an welcher Stelle, da es sich hierbei ja um eine Funktion handelt.

    Hatte schon versucht "XYZ.Dispose()" aber das bringt nicht den erfolg :(

    Dankeee :D
    Wozu willst du das machen? DataTable ist nen Referenztyp. Wennn du die Disposed ist vermutlich auch die Datenquelle des DataGridViews nothing und das DataGridViews leer.
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Ich lese Daten aus einer Externen Datei in eine Datatable ein. Danach werden diese Daten auf einen SQL-Server geschubst.
    Da sich dieser Vorgang ständig wiederholt, muss ich zwischendurch den Arbeitsspeicher wieder frei räumen, da ich sonst irgendwann auf eine "out of memory" exception stoße.

    Das mit dem Datagridview war nur ein Beispiel. Beinhaltet aber das gleiche Problem.

    User kann sich in meiner Anwendung die Daten von externen Dateien anschauen. Wenn der User dies mehrfach hintereinander macht und der Arbeitsspeicher nicht frei geräumt wurde bin ich wieder bei der exception
    Ich hatte das selbe Problem und habe es mit einer Sub gelöst. Ich hoffe das es verständlich ist.


    VB.NET-Quellcode

    1. Public Sub DurchlaufealleTabellen()
    2. For Each SelectedRow as Datarow in AlleTabellen.Rows
    3. UpdateOldDatabase2(cstr(SelectedRow("TableName"))) ' Hier wird die Tabelle eingeladen und bearbeitet sobal die Sub abgearbeitet ist,wird die Tabelle aus dem Arbeitsspeicher entfernt
    4. GC.Collect() 'war glaube ich nicht nötig bei der Variante
    5. GC.WaitForPendingFinalizers() 'war glaube ich nicht nötig bei der Variante
    6. next
    7. End Sub
    8. Private Sub UpdateOldDatabase2(byval Tabellenamen as string)
    9. 'Hier die Tabelle Laden auch SQL etc. nach beendigung alles auf Nothing setzen und alles ist aus dem speicher raus
    10. dim DS as new Dataset
    11. dim Tabelle as new Datatable etc.
    12. end sub
    Habe das Problem in den Griff bekommen.
    Damit ich einen BulkUpload auf den SQL-Server hinbekomme brauche ich ja eine CSV-Datei. Dafür hatte ich eine extra Funktion geschrieben welcher ich die Datatable übergeben hatte.
    Innerhalb dieser Funktion (nachdem die CSV erstellt wurde) konnte ich die DT dann Disposen und somit den Arbeitsspeicher auch wieder frei geben.

    Jetzt läuft es rund :)

    Danke an alle.
    Bulk-Inserts kann man auch mit DataTables durchführen. Hat den Vorteil, dass keine temporäre csv geschrieben und gelesen werden muss.

    Ich täte empfehlen, immer dieselbe DataTable dafür zu nehmen, welche vor dem Bulk-Insert halt geleert und neu befüllt wird.
    So fährt nur eine DataTable im System herum, und nicht jedesmal eine neue, die bei dir offsichtlich nicht richtig resourcen-bereinigt wurden.
    8| wusste ich ja garnicht. Kannst du mir sagen wie das Funktioniert? :)

    Das geht zwar auch jetzt schon unnormal schnell aber wenn ich dadurch noch mehr Zeit sparen kann, bin ich dabei :P

    Momentan mache ich das so:

    VB.NET-Quellcode

    1. Dim cols As String() = {"id", "Bestellnummer", "Lieferant", "Preiseinheit", "Bruttopreis", "EK"}
    2. Dim myfile As String = Application.StartupPath & "\Temp\tblpreise.csv"
    3. Dim rows As Integer = 0
    4. Using con2 As New MySqlConnection(sqlconnectionstring)
    5. Dim bulkloader = New MySqlBulkLoader(con2)
    6. bulkloader.TableName = "tbl_preise"
    7. bulkloader.FieldTerminator = ";"
    8. bulkloader.LineTerminator = "\r\n"
    9. bulkloader.FileName = myfile
    10. bulkloader.NumberOfLinesToSkip = 1
    11. bulkloader.ConflictOption = MySql.Data.MySqlClient.MySqlBulkLoaderConflictOption.Replace
    12. bulkloader.Columns.Clear()
    13. For Each s In cols
    14. bulkloader.Columns.Add(s)
    15. Next
    16. rows = bulkloader.Load()
    17. End Using