简体   繁体   English

使用Async保存FileStream

[英]Using Async to save a FileStream

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: 我正在尝试将文件(BitmapImage)保存到某个位置,但是一旦我使用asyncawait我就会收到错误消息,说明文件正在使用中:

The process cannot access the file 'C:\\Users\\ ... \\image1.jpg' because it is being used by another process. 该进程无法访问文件'C:\\ Users \\ ... \\ image1.jpg',因为它正由另一个进程使用。

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. 当我使用没有 await的代码时,代码完全正常。 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. 谢谢。

In your case when you use Task with await another thread is used to save your encoder . 在您使用Task await情况下,另一个线程用于保存您的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. 现在,您可以在同一任务中创建并保存encoder ,它只使用一个线程。

我认为你应该在Task.Run移动代码,因为它在另一个线程内被调用。

You could encode to a MemoryStream , get the byte array, use WriteAsync on the FileStream , and avoid using Task.Run altogether. 您可以编码为MemoryStream ,获取字节数组,在FileStream上使用WriteAsync ,并完全避免使用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);
}

Note that this will block your thread during the encoding and will use more memory. 请注意,这将在编码期间阻止您的线程,并将使用更多内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM