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.

+3


source to share


3 answers


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.

+5


source


I think you need to move the code inside Task.Run

because it is being called inside another thread.



+4


source


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.

+3


source







All Articles