Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 02.09.2013, 22:50   #1
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
Сообщение IOException

Здравствуйте! Есть статический метод:

Код:
public static void ImagesToGif()
{
	FileStream gifFile = new FileStream("result.gif", FileMode.Create);
	GifBitmapEncoder gifEncoder = new GifBitmapEncoder();
	int currentFrame = 1;
	while (currentFrame < 10)
	{
		string currentFramePath = TEMP_IMG_PATH + @"\frame" + currentFrame.ToString() + ".bmp";
		if (File.Exists(currentFramePath))
		{
			gifEncoder.Frames.Add(BitmapFrame.Create(new Uri(currentFramePath)));
			File.Delete(currentFramePath);
			currentFrame++;
		}
	}
	gifEncoder.Save(gifFile);
}
Этот метод берет из папки n картинок (пока что 10) по одной (frame1.bmp, frame2.bmp и т.д.) и добавляет в gif как кадр:
Код:
gifEncoder.Frames.Add(BitmapFrame.Create(new Uri(currentFramePath)));
после добавления нужно удалить эту картинку из папки, делаю так:
Код:
File.Delete(currentFramePath);
но удаление не происходит, а вместо этого генерируется исключение IOException с сообщением: Процесс не может получить доступ к файлу "C:\Users\...\tempImages\frame1.bmp ", так как этот файл используется другим процессом.

Помогите решить проблему.
pashka_dos вне форума Ответить с цитированием
Старый 03.09.2013, 00:35   #2
Guy
Форумчанин
 
Регистрация: 15.12.2010
Сообщений: 398
По умолчанию

gifFile.Dispose() в конце
Guy вне форума Ответить с цитированием
Старый 03.09.2013, 00:56   #3
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
По умолчанию

Цитата:
Сообщение от Guy Посмотреть сообщение
gifFile.Dispose() в конце
Я пробовал этот способ, все равно не работает. Еще варианты?
pashka_dos вне форума Ответить с цитированием
Старый 03.09.2013, 08:05   #4
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

Скорее всего должно быть что-то типа
Код:
using (var bmp =BitmapFrame.Create(new Uri(currentFramePath)))
    gifEncoder.Frames.Add(bmp);
Если и это не поможет - вообще после всего своего кода добавьте цикл, который удаляет файлы.
phomm вне форума Ответить с цитированием
Старый 03.09.2013, 16:29   #5
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
Сообщение

Спасибо за ответ
Цитата:
Сообщение от phomm Посмотреть сообщение
Скорее всего должно быть что-то типа
Код:
using (var bmp =BitmapFrame.Create(new Uri(currentFramePath)))
    gifEncoder.Frames.Add(bmp);
не помогло.
Цитата:
Если и это не поможет - вообще после всего своего кода добавьте цикл, который удаляет файлы.
Можно было-бы если бы в папке было действительно 10 кадров(как в примере), но у меня перед этим идет раскадровка видео файла (ffMpeg). Даже если видео 30 сек, это примерно 750 кадров по 500kB (или даже больше). В итоге папка будет весить больше 300 MB. Поэтому есть необходимость удалять кадры сразу после добавление их в мой Gif. Или можно как нибудь по-другому сделать?
pashka_dos вне форума Ответить с цитированием
Старый 03.09.2013, 18:10   #6
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

Цитата:
BitmapFrame.Create(new Uri(currentFramePath)
В этот момент внутри BitmapFrame создается BitmapDecoder, который содержит в себе открытый поток, который и использует ваш файл. Поток закрывается только при уничтожении BitmapDecoder'a сборщиком мусора. Попробуйте изменить код так:

Код:
gifEncoder.Frames.Add(BitmapFrame.Create(new Uri(currentFramePath)));
System.GC.Collect();
File.Delete(currentFramePath);
P.S. Это может серьезно отразиться на производительности
Благодарить в репутацию. Проклинать — туда же
Luuzuk вне форума Ответить с цитированием
Старый 03.09.2013, 20:10   #7
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
Сообщение

Цитата:
Сообщение от Luuzuk Посмотреть сообщение
В этот момент внутри BitmapFrame создается BitmapDecoder, который содержит в себе открытый поток, который и использует ваш файл. Поток закрывается только при уничтожении BitmapDecoder'a сборщиком мусора. Попробуйте изменить код так:

Код:
gifEncoder.Frames.Add(BitmapFrame.Create(new Uri(currentFramePath)));
System.GC.Collect();
File.Delete(currentFramePath);
P.S. Это может серьезно отразиться на производительности
К сожалению, не помогло, я даже отключил ffMpeg раскадровку (теперь в папке при запуске уже есть 10 кадров), так что причастность ffMpega к файловому потоку можно отклонить. Также эти файлы у меня явно нигде не открыты (проверял спец утилитой). Будут еще советы?
pashka_dos вне форума Ответить с цитированием
Старый 04.09.2013, 19:28   #8
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
По умолчанию

Ребята, вопрос все еще актуален.
pashka_dos вне форума Ответить с цитированием
Старый 04.09.2013, 20:09   #9
Luuzuk
Форумчанин
 
Аватар для Luuzuk
 
Регистрация: 18.01.2012
Сообщений: 975
По умолчанию

Цитата:
Ребята, вопрос все еще актуален.
Цитата:
BitmapDecoder, который содержит в себе открытый поток, который и использует ваш файл. Поток закрывается только при уничтожении BitmapDecoder'a сборщиком мусора
Причину я уже назвал, что вас еще интересует?
Благодарить в репутацию. Проклинать — туда же
Luuzuk вне форума Ответить с цитированием
Старый 04.09.2013, 20:24   #10
pashka_dos
Пользователь
 
Аватар для pashka_dos
 
Регистрация: 19.11.2011
Сообщений: 83
Сообщение

Я понял причину и последовал вашему совету изменив свой код так:

Код:
gifEncoder.Frames.Add(BitmapFrame.Create(new Uri(currentFramePath)));
System.GC.Collect();
File.Delete(currentFramePath);
Но все равно ошибка: Процесс не может получить доступ к файлу "C:\Users\...\tempImages\frame1 .bmp ", так как этот файл используется другим процессом. Также добавлял
Код:
GC.WaitForPendingFinalizers();
после
Код:
System.GC.Collect();
тоже не помогло. Можно еще как нибудь удалить этот BitmapDecoder?

Как вы уже заметили я начинающий в С#, особенно там, где дело касается многопоточности
pashka_dos вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц