Domanda

Ho un database con circa 180.000 record. Sto cercando di allegare un file pdf a ciascuno di questi record. Ogni pdf è di circa 250 kb di dimensione. Tuttavia, dopo circa un minuto il mio programma inizia a prendere su di un GB di memoria e devo fermarlo. Ho provato a fare in modo che il riferimento a ciascun oggetto LINQ viene rimossa una volta che è aggiornato, ma che non sembra aiuto. Come posso mettere in chiaro il riferimento?

Grazie per il vostro aiuto

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
È stato utile?

Soluzione

Vi suggerisco di eseguire questo in lotti, utilizzando Take (< em> prima la chiamata a ToList) di elaborare un particolare numero di elementi alla volta. Leggi (diciamo) 10, impostare il PDFContent su tutti di loro, chiamata SubmitChanges, e poi ricominciare. (Non sono sicuro se due piedi si dovrebbe iniziare con una nuova DataContext a quel punto, ma potrebbe essere più pulito di farlo.)

Per inciso, il codice per leggere il contenuto di un file è suddiviso in almeno un paio di modi - ma sarebbe più semplice usare File.ReadAllBytes in primo luogo.

Inoltre, il tuo modo di gestire la lista gradualmente restringimento è davvero inefficiente - dopo il recupero 180.000 record, si sta quindi costruendo un nuovo elenco con 179,999 record, poi un altro con 179,998 record etc

.

Altri suggerimenti

fa il DataContext hanno ObjectTrackingEnabled impostata su true (il valore predefinito)? Se è così, allora sarà cercare di mantenere un registro di essenzialmente tutti i dati che tocca, impedendo così il garbage collector di essere in grado di raccogliere qualsiasi di esso.

Se è così, si dovrebbe essere in grado di risolvere la situazione periodicamente smaltire il DataContext e la creazione di uno nuovo, o girando oggetto di monitoraggio off.

OK. Per utilizzare la più piccola quantità di memoria che dobbiamo aggiornare il DataContext in blocchi. Ho messo un codice di esempio. Potrebbe avere errori sytax dal momento che sto utilizzando il Blocco note di digitare in.

    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

Per ottimizzare ulteriormente la velocità si può ottenere il recordID di in un array da AllItems come un tipo anonimo, e DelayLoading impostato su quel campo per PDF.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top