Using Async to Save FileStream
I'm trying to save a file (BitmapImage) in a specific location, but as soon as I use async
and await
, I get a message that the file is in use:
The process cannot access the file 'C: \ Users \ ... \ image1.jpg' because it is in use 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 await
, the code works fine. I think it might be because another thread might be using it, but can anyone help or explain to me the work around my problem? Thank.
source to share
In your case, when you use Task
with await
, a encoder
different stream is used to save . But your coder is also being used by your main thread, so the new thread cannot 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 yours encoder
in the same task and will only use one thread.
source to share
You can code before MemoryStream
, get a byte array, use WriteAsync
in, FileStream
and not use at all Task.Run
.
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);
}
Please note that this will block your stream while encoding and will use more memory.
source to share