Frage

habe ich eine Datenbank mit über 180.000 Datensätzen. Ich versuche, eine PDF-Datei zu jedem dieser Datensätze zu befestigen. Jede pdf ist etwa 250 kb groß. Doch nach etwa einer Minute meines Programm beginnt etwa um einen GB Speicher nehmen, und ich habe ihn zu stoppen. Ich habe versucht, es zu tun, so der Hinweis auf jedes Linq Objekt entfernt wird, sobald es aktualisiert wird, aber das scheint nicht zu helfen. Wie kann ich es den Verweis löschen?

Danke für Ihre Hilfe

Private Sub uploadPDFs(ByVal args() As String)
    Dim indexFiles = (From indexFile In dataContext.IndexFiles
                     Where indexFile.PDFContent = Nothing
                     Order By indexFile.PDFFolder).ToList
    Dim currentDirectory As IO.DirectoryInfo
    Dim currentFile As IO.FileInfo
    Dim tempIndexFile As IndexFile

    While indexFiles.Count > 0
        tempIndexFile = indexFiles(0)
        indexFiles = indexFiles.Skip(1).ToList
        currentDirectory = 'I set the directory that I need
        currentFile = 'I get the file that I need
        writePDF(currentDirectory, currentFile, tempIndexFile)
    End While
End Sub

Private Sub writePDF(ByVal directory As IO.DirectoryInfo, ByVal file As IO.FileInfo, ByVal indexFile As IndexFile)
    Dim bytes() As Byte
    bytes = getFileStream(file)
    indexFile.PDFContent = bytes
    dataContext.SubmitChanges()
    counter += 1
    If counter Mod 10 = 0 Then Console.WriteLine("     saved file " & file.Name & " at " & directory.Name)
End Sub


Private Function getFileStream(ByVal fileInfo As IO.FileInfo) As Byte()
    Dim fileStream = fileInfo.OpenRead()
    Dim bytesLength As Long = fileStream.Length
    Dim bytes(bytesLength) As Byte

    fileStream.Read(bytes, 0, bytesLength)
    fileStream.Close()

    Return bytes
End Function
War es hilfreich?

Lösung

Ich schlage vor, Sie führen dies in den Reihen, mit Take (< em> vor der Anruf an ToList) eine bestimmte Anzahl von Elementen zu einem Zeitpunkt, zu verarbeiten. Read (sagen wir) 10, stellen Sie die PDFContent auf alle von ihnen, Anruf SubmitChanges, und dann wieder von vorne anfangen. (Ich bin nicht sicher, ob offhand Sie mit einem neuen DataContext an diesem Punkt beginnen sollten, aber es könnte sauberste so zu tun.)

Als Nebenwirkung des Code den Inhalt einer Datei wird gebrochen in mindestens ein paar Möglichkeiten zu lesen - aber es wäre einfacher, nur zu verwenden File.ReadAllBytes an erster Stelle.

Auch Ihr Weg, um die Liste nach und nach schrumpfen Handhabung ist wirklich ineffizient - nach 180.000 Datensätze zu holen, sind Sie dann den Aufbau eine neue Liste mit 179.999 Datensätze, dann noch mit 179.998 Datensätze etc

.

Andere Tipps

Hat die Datacontext ObjectTrackingEnabled auf true gesetzt (der Standardwert)? Wenn ja, dann wird es versuchen, einen Datensatz zu halten im wesentlichen alle Daten, die er berührt, wodurch der Garbage Collector verhindert in der Lage, irgendetwas davon zu sammeln.

Wenn ja, sollten Sie in der Lage, die Situation zu beheben, indem Sie in regelmäßigen Abständen die Datacontext entsorgen und einen neuen zu erstellen, oder dreht Objektverfolgung aus.

OK. Um die kleinste Menge an Speicher zu verwenden, müssen wir die Datacontext in Blöcken aktualisieren. Ich habe einen Beispielcode unten setzen. Könnte sytax Fehler haben, da ich Notizblock bin mit ihm zu geben.

    Dim DB as YourDataContext = new YourDataContext
    Dim BlockSize as integer = 25
    Dim AllItems = DB.Items.Where(function(i) i.PDFfile.HasValue=False)

    Dim count = 0
    Dim tmpDB as YourDataContext = new YourDataContext


While (count < AllITems.Count)

    Dim _item = tmpDB.Items.Single(function(i) i.recordID=AllItems.Item(count).recordID)
    _item.PDF = GetPDF()

    Count +=1

    if count mod BlockSize = 0 or count = AllItems.Count then
        tmpDB.SubmitChanges()
         tmpDB =  new YourDataContext
           GC.Collect()
    end if

End While

weiter zu optimieren die Geschwindigkeit Sie die recordID der in ein Array von AllItems als anonymer Typ und Satz DelayLoading auf für das PDF-Feld erhalten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top