异步调用WriteAsync,我怎么知道它什么时候完成?

时间:2014-02-13 20:29:32

标签: c# visual-studio-2012 asynchronous windows-phone-8 async-await

我使用异步调用将文件写入IsolatedStorageFile

async void  Base64ToImage()
{
   byte[] data;
   using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication())
   {
     using (IsolatedStorageFileStream isfs = isf.OpenFile("image.p64", FileMode.Open, FileAccess.ReadWrite))
      {
         data = new byte[isfs.Length];
         isfs.Read(data, 0, data.Length);
         isfs.Close();
      }

     using (IsolatedStorageFileStream stream = isf.OpenFile("newReConvertedFile.png", FileMode.Create))
     {
         await stream.WriteAsync(data, 0, data.Length);

 ///////////////////The problem is here, how would i know when WriteAsync is complete to then fire the reload method?
        //reLoadFile();
      }
   }
}

我需要知道WriteAsync何时完成以另一种方法重新加载该文件,我将如何做到这一点?

编辑:

实际上我的第一个想法是将文件保存到isostorage然后将图像uri发送到该文件,但是你不能将uri设置为isosorage for images或者至少我无法显示

我最初的想法是等待方法调用重新加载文件,但我得到一个错误“???没有返回任务,也无法等待。考虑改变它以返回“但我不知道如何去做。

这里的想法是将多个图像转换为Base64(SQLite数据库),但只加载选定的图像,以便显示。

reLoadFile方法如下

async void reLoadFile()
{
    byte[] newFile;
    using (IsolatedStorageFile newFileLoc = IsolatedStorageFile.GetUserStoreForApplication())
    {
        using (IsolatedStorageFileStream newFileStream = newFileLoc.OpenFile("newReConvertedFile.png", FileMode.Open, FileAccess.ReadWrite))
        {
            newFile = new byte[newFileStream.Length];
            newFileStream.Read(newFile, 0, newFile.Length);
            newFileStream.Close();

            var ms = new MemoryStream(newFile); 
            var image = new BitmapImage(); 
            image.SetSource(ms); 
            theImage.Source = image; 
        }
     }
 }

我一直在搜索这些帖子,但我无法让它发挥作用,因为如果我立即调用它,我会得到一个例外。 我需要做的是打开文件将其从base64转换为.png,然后在保存后加载.png文件。 如果有人可以帮助我,我会很感激。

感谢鲍勃。

3 个答案:

答案 0 :(得分:3)

1)reloadFile不需要async只需在方法中使用await关键字时使用{<1}}

2)BaseTo64Image需要声明为async Task Base64ToImage(),否则Base64ToImage()的调用者将无法判断它何时完成。

3)isfs.Read(data, 0, data.Length);不好,只是因为您请求了data.Length个字节并不意味着您会被data.Length读入,您需要检查int读取返回值循环或使用CopyTo(Stream)复制到另一个流。

4)(实际上回答你的问题)关键字await将停止处理函数并等待函数完成。当您点击await关键字时,您的Base64ToImage()函数将在该点返回,其中Task代表该函数中的其余代码,由您自己执行的操作{ {1}}从函数返回。

以下是使用所有建议的代码的简化版本

Task

但是,如果您正在做的就是这样,并且您只是使用async Task Base64ToImage() { using (IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication()) using (IsolatedStorageFileStream stream = isf.OpenFile("newReConvertedFile.png", FileMode.Create)) using (IsolatedStorageFileStream isfs = isf.OpenFile("image.p64", FileMode.Open, FileAccess.ReadWrite)) { await isfs.CopyToAsync(stream); } await ReLoadFile(); } async Task ReLoadFile() { using (IsolatedStorageFile newFileLoc = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream newFileStream = newFileLoc.OpenFile("newReConvertedFile.png", FileMode.Open, FileAccess.ReadWrite)) { var ms = new MemoryStream(); var image = new BitmapImage(); await newFileStream.CopyToAsync(ms); ms.Position = 0; image.SetSource(ms); theImage.Source = image; } } } 作为临时文件,则可以将代码简化为

newReConvertedFile.png

答案 1 :(得分:1)

请在下一行调用它。 await将异步等待,直到WriteAsync完成。这就是“async / await”的优点,它可以让你编写看似同步的异步代码。

 using (IsolatedStorageFileStream stream = isf.OpenFile("newReConvertedFile.png", FileMode.Create))
 {
     await stream.WriteAsync(data, 0, data.Length);
     reLoadFile();
  }

我错过了什么吗?

答案 2 :(得分:1)

WriteAsync方法在返回Task完成时已完成。

等待任务完成,只需await

await stream.WriteAsync(data, 0, data.Length);
// WriteAsync is complete.