2009-10-30 16 views
10

Robię połączenie wielu plików tiff multi-image do pojedynczego pliku tiff wielu obrazów i mam problem z usunięciem plików źródłowych tiff, ponieważ klasa Image nadal trzyma na nich uchwyt.Używanie Image.FromFile nie zwalnia uchwytu pliku

Czytam obrazu TIFF przez Image.FromFile:

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

Po czym czytam pozostałe zdjęcia TIFF w taki sam sposób i dołączyć je do wynikowego obrazu TIFF.

Kiedy skończę używam tego kodu, aby zwolnić referencje i zapisać plik wynikowy:

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

Teraz problem jest, że uchwyt na plikach nadal istnieje (a więc pliki mogą nie zostać usunięte) chyba że zadzwonię do GC.Collect() po wywołaniu resultTiff.Dispose().

Możesz sobie wyobrazić, że nie czuję się komfortowo, dzwoniąc do GC, więc czy istnieje inny sposób osiągnięcia tego?

Odpowiedz

17

Najlepszym sposobem, aby rozwiązać problem z Image.FromFile którym pozostawia otwarte uchwyty plików jest użycie Image.FromStream zamiast.

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

Korzystanie wyraźny Dispose(), z użyciem() oświadczenie lub ustawienie wartości NULL nie rozwiązuje problemu, aż do zbierania śmieci dzieje. Zmuszanie do zbierania śmieci jest generalnie złym pomysłem.

+2

+1 za tę odpowiedź. 'Image.FromFile' nie zawsze robi dokładnie to, co należy. Zastąpienie go ręcznym otwarciem strumienia pliku, a następnie załadowanie mapy bitowej stamtąd zapewnia większą elastyczność. – stakx

+0

Z jakiegoś powodu "FileStream" wciąż dawał mi ten sam problem. Zamiast tego użyłem 'Image.FromStream (new MemoryStream (File.ReadAllBytes (path))), który działał dobrze. – William

1

Można spróbować:

resultTiff = null; 
+0

tyłek tak jak nie musisz tego robić - to działa. Miałem aplikację graficzną, która ładowała 1000 obrazów w pętli i przetwarzała je. gdybym nie miał "img = null" w pętli, bardzo szybko dostałbym błędy OOM. – Pondidum

+0

@Pondium: Ja też miałem ten problem. Jako zdarzenie, podejrzewam, że może to być spowodowane nie tylko niewystarczającą pamięcią, ale także brakiem uchwytów GDI. – stakx

5

Lub spróbuj:

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

Podczas używania 'using' jest zdecydowanie dobrą rekomendacją, prawdopodobnie nie rozwiąże konkretnego problemu Gorana. Przykładowy kod podany w pytaniu już wywołuje "Dispose" (w wyjątkowych okolicznościach). – LukeH

+0

Dziękuję wam za odpowiedź. Tak się złożyło, że miałem usterkę gdzieś indziej w kodzie i kiedy naprawiłem, że użycie Just Dispose rozwiązało moje problemy. Nie wyrzucałem odwołań do plików, do których byłem _appending_ do pierwszego pliku. Kiedy to poprawiłem, wszystko zaczęło działać świetnie. – Goran

Powiązane problemy