Reputation: 1300
I am trying to save a file(BitmapImage) to a certain location, but as soon as I use async
& await
I get an error saying the file is in use:
The process cannot access the file 'C:\Users\ ... \image1.jpg' because it is being used by another process.
My coding:
BitmapImage image = new BitmapImage(new Uri(oldImagePath));
var encoder = new JpegBitmapEncoder() { QualityLevel = 17 };
encoder.Frames.Add(BitmapFrame.Create(image));
using (var filestream = new FileStream(GetImageLocation(), FileMode.Create))
await Task.Run(() => encoder.Save(filestream)); //Error here
When I use the code without the await
, the code works perfectly fine. I think it might be because another thread might be using it, but can anyone help or explain to me a work around for my issue? Thank you.
Upvotes: 4
Views: 5683
Reputation: 32286
You could encode to a MemoryStream
, get the byte array, use WriteAsync
on the FileStream
, and avoid using Task.Run
altogether.
BitmapImage image = new BitmapImage(new Uri(oldImagePath));
var encoder = new JpegBitmapEncoder() { QualityLevel = 17 };
encoder.Frames.Add(BitmapFrame.Create(image));
using (var mem = new MemoryStream())
using (var filestream = new FileStream(GetImageLocation(), FileMode.Create))
{
encoder.Save(mem);
var data = mem.ToArray();
await filestream.WriteAsync(date, 0, data.Length);
}
Note that this will block your thread during the encoding and will use more memory.
Upvotes: 4
Reputation: 12201
In your case when you use Task
with await
another thread is used to save your encoder
. But your encoder is also used by your main thread so new thread can't use it.
Change your code a little:
await Task.Run(() =>
{
using (var filestream = new FileStream(GetImageLocation(), FileMode.Create))
{
BitmapImage image = new BitmapImage(new Uri(oldImagePath));
var encoder = new JpegBitmapEncoder() { QualityLevel = 17 };
encoder.Frames.Add(BitmapFrame.Create(image));
encoder.Save(filestream);
}
}
Now you create and save your encoder
in the same task and it will use only one thread.
Upvotes: 8
Reputation: 2108
I think you should move the code inside the Task.Run
, because it gets called inside another thread.
Upvotes: 4