Не удалось разблокировать изображение, используемое в picturebox

Мне нужно переместить/переименовать некоторые изображения, которые загружаются внутри изображений, изображения хранятся в папке по пути к исполняемому файлу приложения. Прежде чем я смогу переместить/переименовать любое изображение, я должен убедиться, что оно не используется, поэтому я попытался загрузить другое изображение из пути к исполняемому файлу приложения в это изображение, а также попытался «обнулить» свойство изображения изображения.

Если я хочу двигаться дальше в своей программе, изображение все еще заблокировано, я проверил это, используя следующий код:

protected virtual bool IsFileLocked(FileInfo file)
    {
        FileStream stream = null;

        try
        {
            stream = file.Open(FileMode.Open, FileAccess.Read, FileShare.None);
        }
        catch (IOException)
        {
            return true;
        }
        finally
        {
            if (stream != null)
                stream.Close();
        }
        return false;
    }

Я также пытался использовать код отсюда: Какой процесс блокирует файл?

Что вернуло мне следующее: System.Collections.Generic.List´1[System.Diagnostics.Process]

Я должен сказать вам, что я также борюсь с AccessViolationException, используя те же изображения и методы. Я не совсем уверен, что это одна и та же проблема ... я неправильно сохранил изображения или так, как я их использую? Дайте мне знать, если вам нужно больше кода или информации!

ИЗМЕНИТЬ:

И ссылка от TaW, и ответ от Anon Coward не сработали для меня, и я действительно изо всех сил старался заставить ее работать, я пытался удалить и обнулить изображение, изображение и т. д. Я нашел решение, смешанное с вашим предложением, но это очень грязно...

var image2 = Image.FromFile(infos[i].FullName);
                                MemoryStream ms = new MemoryStream();
                                if (ImageFormat.Jpeg.Equals(image2.RawFormat))
                                {
                                    // JPEG
                                    image2.Save(ms, ImageFormat.Jpeg);
                                }
                                else if (ImageFormat.Png.Equals(image2.RawFormat))
                                {
                                    // PNG
                                    image2.Save(ms, ImageFormat.Png);
                                }
                                else if (ImageFormat.Gif.Equals(image2.RawFormat))
                                {
                                    // Bitmap
                                    image2.Save(ms, ImageFormat.Bmp);
                                }
                                else if (ImageFormat.Icon.Equals(image2.RawFormat))
                                {
                                    // Icon
                                    image2.Save(ms, ImageFormat.Icon);
                                }
                                image2.Dispose();

                                System.GC.Collect();
                                System.GC.WaitForPendingFinalizers();

                                System.IO.File.Delete(infos[i].FullName);

                                Image newImg = Image.FromStream(ms);
                                newImg.Save(neuer_name2);
                                newImg = null;

Я знаю, что использование GarbageCollection — неправильный путь, но я понятия не имею, что блокирует изображения... поэтому я все еще ищу здесь реальное решение.


person user3868224    schedule 09.07.2016    source источник
comment
Код, который загружает и пытается изменить/переместить их, будет даже интереснее, чем тот, который пытается разблокировать. Пожалуйста, покажите все. /а>?   -  person TaW    schedule 09.07.2016
comment
Я видел ссылку, и я работаю над ней прямо сейчас, если это не поможет, я отредактирую свой исходный вопрос.   -  person user3868224    schedule 09.07.2016
comment
Смотрите редактирование моего ответа, я забыл, что есть старая проблема GDI +, с которой вы можете столкнуться.   -  person Anon Coward    schedule 12.07.2016


Ответы (1)


Когда вы устанавливаете для свойства значение null, вы только помечаете объект как доступный для сборки мусора в какой-то момент в будущем, поэтому дескриптор файла для объекта останется открытым до определенного момента в будущем.

Если вы планируете изменить файл, вам нужно сделать две вещи: сделать свойство Null, чтобы PictureBox не пытался его использовать, а также удалить само изображение, чтобы дескриптор файла был закрыт:

var image = pictureBox1.Image;
pictureBox1.Image = null;
image.Dispose();

Кроме того, существует проблема с GDI+, с которой вы можете столкнуться. Вам нужно будет запретить конструктору изображения сохранять ссылку на файл в первую очередь, вы можете легко сделать это, сначала прочитав его в MemoryStream, а затем передав его конструктору:

Image image = Image.FromStream(new MemoryStream(File.ReadAllBytes("test.png")))
person Anon Coward    schedule 09.07.2016