Reputation: 1009
I'm moving some long running code to background using async/await etc, but hitting the subject-line error. I'm well aware I cannot update my WPF UI Controls from the task (and I've added dispatcher appropriately) but this error occurs simply updating an object in my class. Example:
private WriteableBitmap TempImage;
public async void StartProcessing()
{
WriteableBitmap LoadedImage = new WriteableBitmap(await LoadImage(0)); //ERROR HERE
LoadedImage.Freeze();
TempImage = LoadedImage;
// do more stuff
}
private Task<BitmapImage> LoadImage(int imageIndex)
{
return Task.Run(() =>
{
FileStream fileStream = new FileStream(fileList[0], FileMode.Open, FileAccess.Read);
var img = new BitmapImage();
img.BeginInit();
img.StreamSource = fileStream;
img.EndInit();
return img;
});
}
The "freeze" stuff is my current attempt to resolve it, but it still occurs as soon as I try to assign the returned image to my class-level variable. I'm assuming this is because my UI thread instantiated the class, and thus the variable is in the UI thread context, but not sure how to resolve it?
Upvotes: 0
Views: 1037
Reputation: 128145
You may also have to freeze the BitmapImage created in LoadImage. Moreover, you should also close the FileStream after loading the image. Therefore you need to set the BitmapCacheOption.OnLoad
flag.
using (var fileStream = new FileStream(fileList[0], FileMode.Open, FileAccess.Read))
{
var img = new BitmapImage();
img.BeginInit();
img.CacheOption = BitmapCacheOption.OnLoad; // here
img.StreamSource = fileStream;
img.EndInit();
img.Freeze(); // and here
return img;
}
Upvotes: 2
Reputation: 22021
You can use the Dispatcher
to marshal the call that acceses the WriteableBitmap
onto the thread that created it.
Upvotes: 0