Question

J'ai une base de données avec environ 180 000 dossiers. J'essaie de joindre un fichier pdf à chacun de ces dossiers. Chaque pdf est d'environ 250 kb. Cependant, au bout d'environ une minute mon programme commence à prendre au sujet d'un Go de mémoire et je dois l'arrêter. J'ai essayé de le faire de sorte que la référence à chaque objet LINQ est retiré une fois qu'il est mis à jour, mais cela ne semble pas aider. Comment puis-je faire clairement la référence?

Merci pour votre aide

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
Était-ce utile?

La solution

Je vous suggère d'effectuer cela en lots, en utilisant Take (< em> avant l'appel à ToList) pour traiter un nombre particulier d'éléments à la fois. Lire (par exemple) 10, réglez le PDFContent sur tous d'entre eux, appel SubmitChanges, puis recommencer. (Je ne suis pas sûr que désinvolture vous devriez commencer par une nouvelle DataContext à ce moment-là, mais il pourrait être plus propre de le faire.)

En aparté, votre code pour lire le contenu d'un fichier est divisé en au moins deux façons - mais il serait plus simple d'utilisation File.ReadAllBytes en premier lieu.

En outre, votre façon de gérer la liste progressivement rétrécissement est vraiment inefficace - après extraction 180.000 dossiers, vous construisez alors une nouvelle liste avec 179,999 enregistrements, puis un autre avec 179,998 enregistrements etc

.

Autres conseils

Est-ce que les DataContext ont ObjectTrackingEnabled valeur true (la valeur par défaut)? Si oui, alors il va essayer de tenir un registre de toutes les données essentiellement qu'il touche, empêchant ainsi le collecteur des ordures d'être en mesure de recueillir tout cela.

Si oui, vous devriez être en mesure de corriger la situation en disposant périodiquement le DataContext et la création d'un nouveau ou d'un objet tournant le suivi de.

OK. Pour utiliser la plus petite quantité de mémoire que nous devons mettre à jour le datacontext en blocs. J'ai mis un code exemple ci-dessous. Peut contenir des erreurs de sytax depuis que je suis en utilisant le bloc-notes pour le saisir.

    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

Pour plus d'optimiser la vitesse que vous pouvez obtenir de l'recordID dans un tableau de AllItems comme un type anonyme, et ensemble DelayLoading sur ce champ pour PDF.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top