2009-10-30 2 views
10

Ich mache eine Verknüpfung von mehreren Multi-Image-TIFF-Dateien zu einer einzigen Multi-Image-TIFF-Datei und ein Problem mit dem Löschen der Quell-TIFF-Dateien, da die Klasse Bild weiterhin den Griff auf ihnen halten.Verwendung von Image.FromFile nicht Handle für eine Datei

Ich bin ein TIFF-Bild durch Image.FromFile Lesen:

Bitmap resultTiff = (Bitmap) Image.FromFile(strImageFile); 

Nach dem ich alle anderen TIFF-Bilder auf die gleiche Weise lesen und hängen Sie sie an dem resultierenden TIFF-Bild.

Als ich beende ich diesen Code verwenden Verweise zu lösen und die daraus resultierende Datei zu speichern:

ep.Param[0] = new EncoderParameter(enc, (long) EncoderValue.Flush); 
resultTiff.SaveAdd(ep); 
resultTiff.Dispose(); 

Nun ist das Problem, dass der Griff auf die Dateien existiert noch (und daher Dateien können nicht gelöscht werden) außer ich rufe den GC.Collect() nach dem resultTiff.Dispose() Anruf an.

Sie können sich vorstellen, dass ich mich nicht sehr wohl fühle, wenn ich GC anrufe. Gibt es einen anderen Weg, dies zu erreichen?

Antwort

17

Der beste Weg, um das Problem mit Image.FromFile zu lösen, wobei es Datei-Handles offen lässt Image.FromStream stattdessen verwenden.

using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) 
{ 
    using (Image original = Image.FromStream(fs)) 
    { 
     ... 

eine explizite Dispose() verwenden, eine mit() Anweisung oder den Wert auf Null Einstellung löst nicht das Problem, bis eine Garbage Collection passiert. Das Erzwingen einer Speicherbereinigung ist im Allgemeinen eine schlechte Idee.

+2

+1 für diese Antwort. 'Image.FromFile' macht nicht immer genau das Richtige. Ersetzen Sie es, indem Sie einen Dateistrom manuell öffnen und dann die Bitmap von dort laden, gibt Ihnen etwas mehr Flexibilität. – stakx

+0

Aus irgendeinem Grund gab 'FileStream' mir immer noch das gleiche Problem. Stattdessen habe ich Image.FromStream (new MemoryStream (File.ReadAllBytes (path))) verwendet, was gut funktioniert hat. – William

1

können Sie versuchen:

resultTiff = null; 
+0

so viel wie Sie dies nicht tun sollten - es funktioniert. Ich hatte eine Bild-App, die 1000 Bilder in einer Schleife geladen und verarbeitet hat. wenn ich nicht 'img = null' in der Schleife hätte, würde ich OOM Fehler sehr schnell bekommen. – Pondidum

+0

@Pondium: Ich hatte dieses Problem auch. Als Nebenbemerkung vermute ich, dass dies nicht nur auf unzureichenden Speicher zurückzuführen ist, sondern auch auf einen Mangel an GDI-Handles. – stakx

5

Oder versuchen:

Using(Bitmap resultTiff = (Bitmap) Image.FromFile(strImageFile)) 
{ 
    ep.Param[0] = new EncoderParameter(enc, (long) EncoderValue.Flush); 
    resultTiff.SaveAdd(ep); 
} 
+1

Während die Benutzung von 'using' definitiv eine gute Empfehlung ist, wird es Goran's spezielles Problem wahrscheinlich nicht lösen. Der Beispielcode, der in der Frage angegeben wird, ruft bereits "Dispose" auf (in Ausnahmefällen). – LukeH

+0

Vielen Dank für Ihre Antwort. Es passierte einfach, dass ich irgendwo anders im Code einen Fehler hatte, und als ich das Problem behoben hatte, löste ich mit Dispose nur meine Probleme. Ich verfügte nicht über Verweise auf die Dateien, die ich an die erste Datei angehängt hatte. Als ich das korrigierte, fing alles großartig an. – Goran