I am using a FileSystemWatcher to raise the event when an image file is edited on Paint and update the preview image control using it. But setting the file as a source second time, it throws an error because the file is still in use by another process. So I discovered this is because of FileSystemWatcher.
I have this code:
private void btnEdit_Click(object sender, RoutedEventArgs e)
{
if (!File.Exists(lastImage)) return;
FileSystemWatcher izleyici = new FileSystemWatcher(System.IO.Path.GetDirectoryName( lastImage),
System.IO.Path.GetFileName(lastImage));
izleyici.Changed += izleyici_Changed;
izleyici.NotifyFilter = NotifyFilters.LastWrite;
izleyici.EnableRaisingEvents = true;
ProcessStartInfo info = new ProcessStartInfo();
info.FileName = lastImage;
info.Verb = "edit";
Process.Start(info);
}
void izleyici_Changed(object sender, FileSystemEventArgs e)
{
//I want to add code here to release the file. Dispose() not worked for me
setImageSource(lastImage);
}
void setImageSource(string file)
{
var bitmap = new BitmapImage();
using (var stream = new FileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
}
ssPreview.Source = bitmap;
}
In this code I want to release the file before updating the Image
control. I tried Dispose
but it was not worked. How can I do that?
The file is neither locked by the FileSystemWatcher, nor by MS Paint. What actually happens is that you get an InvalidOperationException
, because the FileSystemWatcher's Changed
event is not fired in the UI thread, and hence the handler method can't set the Image control's Source
property.
Invoking the image loading code in a Dispatcher action solves the issue:
void setImageSource(string file)
{
Dispatcher.Invoke(new Action(() =>
{
using (var stream = new FileStream(
file, FileMode.Open, FileAccess.Read, FileShare.Read))
{
ssPreview.Source = BitmapFrame.Create(
stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
}
}));
}