Освободить файл от процесса

251
28 марта 2019, 04:00

У меня есть круг и его заливка это картинка которая в папке \Resources\Images\. При нажатии на нее пользователь может выбрать другую, которая будет на месте старой находиться и она тоже переноситься в папку где старая картинка. Но после "обновления" картинки, старая нам больше не нужна, и её нужно удалить. генерируется исключение

System.IO.IOException: "Процесс не может получить доступ к файлу "...\Resources\Images\avatar.jpg", так как этот файл используется другим процессом."

Как освободить этот файл для его дальнейшего удаления. Вот код сейчас:

OpenFileDialog openFileDialog = new OpenFileDialog
{
    Filter = "Image Files|*.jpg;*.jpeg;*.png;"
};
openFileDialog.ShowDialog();
string PhotoPath = openFileDialog.FileName;
if (PhotoPath != "")
{
    string fileName = PhotoPath.Split('\\').Last();
    string avatarPath = $@"Resources\Images\avatar.{fileName.Split('.').Last()}";
    if (File.Exists(avatarPath))
        File.Delete(avatarPath);
    File.Copy(PhotoPath, avatarPath);
    user.LinkToPhoto = avatarPath;
    var img = new BitmapImage(new Uri($"{user.LinkToPhoto}", UriKind.Relative));
    User_Avatar.Fill = new ImageBrush(img);
}
Answer 1

Вам следует ознакомиться со стандартной библиотекой .Net:

string fileName = PhotoPath.Split('\\').Last();
// ===>
string fileName = Path.GetFileName(PhotoPath);
fileName.Split('.').Last()
// ===>
Path.GetExtension(fileName)
if (File.Exists(avatarPath))
    File.Delete(avatarPath);
File.Copy(PhotoPath, avatarPath);
// ===>
File.Copy(PhotoPath, avatarPath, overwrite: true);

Далее, используйте следующий метод для неблокирующей загрузки ImageSource:

public static ImageSource NonBlockingLoad(string path)
{
    var image = new BitmapImage();
    image.BeginInit();
    image.CacheOption = BitmapCacheOption.OnLoad;
    image.UriSource = new Uri(path);
    image.EndInit();
    // На случай, если захотите загружать картинки фоново,
    //  а это надо сделать, т.к. пользователь может указать
    //  путь к медленному устройству или сетевой путь
    image.Freeze();
    return image;
}

Ну и, наконец, если вы используете для хранения настроек пользователя локальную БД или нечто подобное, может иметь смысл изменить разрешение картинки (зачем вам FullHD аватарки?) и сохранить картинку прямо в это хранилище в виде массива байтов (или в формате вроде base64), тогда можно будет использовать метод показанный в этом ответе: https://stackoverflow.com/a/9564425/6766879

READ ALSO
Подмена метода C#

Подмена метода C#

Вопрос не нов, но в сети я не смог найти ответа к сожалениюВ общем ситуация следующая,у меня есть класс к примеру:

173
Как добавить данные в базу MySQL из DataGrid C#?

Как добавить данные в базу MySQL из DataGrid C#?

Как добавить данные вводимые в DataGrid в базу данных MySQL? Добавленных данных нет в базе, и ошибок, почему это происходит тоже нетЯ пытаюсь решить...

222
Как я могу получить выбранный элемент из DataGrid WPF?

Как я могу получить выбранный элемент из DataGrid WPF?

Я получаю DataTable из базы данных, после заполняю им DataGrid:

185
Как в wp_remote_request обработать таймаут?

Как в wp_remote_request обработать таймаут?

Всем привет! Делаю запрос через wp_remote_request с заданным тайм аутом, не понимаю как мне обрабатывать ситуацию если в заданный тайм аут ответ не пришел...

178