在Windows8中,如何将异步方法视为同步方法?

时间:2012-10-24 04:24:19

标签: windows-8 microsoft-metro windows-runtime

StoreBitmapImage是将位图图像存储到磁盘的同步函数。但是当我编译时,我得到System.AggregateException,我做错了什么?

public static void StoreBitmapImage(string uri,string fileName)
    {
        HttpClient httpClient = new HttpClient();
        IRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
        Stream responseStream = httpClient.GetStreamAsync(new Uri(uri)).Result;//Get BMP from web

        Byte[] buffer = new byte[500];
        int read;

        do
        {
            read = responseStream.ReadAsync(buffer, 0, buffer.Length).Result;
            randomAccessStream.WriteAsync(buffer.AsBuffer()).GetResults();

        } while (read != 0);//convert responseStream into bytes

        randomAccessStream.FlushAsync().GetResults();
        randomAccessStream.Seek(0);

        StorageFolder folder = ApplicationData.Current.RoamingFolder;//prepare folder

        StorageFile file = null;
        if (folder != null && buffer != null)
            file = folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting).GetResults();
        else
            return;

        using (IRandomAccessStream rStream = file.OpenAsync(FileAccessMode.ReadWrite).GetResults())
        using (IOutputStream oStream = rStream.GetOutputStreamAt(0))
        {
            DataWriter writer = new DataWriter(oStream);
            writer.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
            writer.WriteBytes(buffer);
            writer.StoreAsync().GetResults();
        }//write to folder
    }

4 个答案:

答案 0 :(得分:1)

System.AggregateException表示代码中有多个Exceptions。你能解释 如何将异步方法视为同步方法的意思吗?

答案 1 :(得分:1)

尝试同步进行此类操作不是一个好习惯。在WinRT中可以很容易地从Web保存文件,请查看https://winrtxamltoolkit.codeplex.com/SourceControl/changeset/view/0657c67a93d5#WinRTXamlToolkit%2fNet%2fWebFile.cs

答案 2 :(得分:1)

您尝试在调用异步方法时获得的IAsyncOperation对象上调用GetResults。在大多数情况下,这将失败,因为异步方法返回时异步操作未完成。您获得的AggregateException可能是尝试尽早获得结果的结果。您可以使用以下代码同步调用异步方法:

Task<StorageFile> task = folder.CreateFileAsync(fileName,
   CreationCollisionOption.ReplaceExisting).AsTask();

 // Read the result which will synchronously wait for the async operation
 StorageFile file = task.Result;

由于Windows应用程序的Microsoft指南不允许同步调用异步代码,并且使用此类代码的应用程序可能无法通过认证,因此更好的解决方案是使您的方法同步并使用await调用异步方法。这当然涉及使用await调用您的方法本身。但是如果你设计一个新的应用程序,这应该不是一个问题。

在你的辩护中:同步调用异步代码可能适用于“概念验证”应用程序或使用WinRT类型的桌面应用程序(引用相应的.winmd文件)。

答案 3 :(得分:1)

async代码的主要指导原则之一是“async一直向下”;换句话说,不要阻止async代码。

遵守本指南,您应该制作方法async

public static async Task StoreBitmapImage(string uri, string fileName)
{
  HttpClient httpClient = new HttpClient();
  IRandomAccessStream randomAccessStream = new InMemoryRandomAccessStream();
  Stream responseStream = await httpClient.GetStreamAsync(new Uri(uri)); //Get BMP from web

  Byte[] buffer = new byte[500];
  int read;

  do
  {
    read = await responseStream.ReadAsync(buffer, 0, buffer.Length);
    await randomAccessStream.WriteAsync(buffer.AsBuffer());
  } while (read != 0);//convert responseStream into bytes

  await randomAccessStream.FlushAsync();
  randomAccessStream.Seek(0);

  StorageFolder folder = ApplicationData.Current.RoamingFolder;//prepare folder

  StorageFile file = null;
  if (folder != null && buffer != null)
    file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
  else
    return;

  using (IRandomAccessStream rStream = await file.OpenAsync(FileAccessMode.ReadWrite))
  using (IOutputStream oStream = rStream.GetOutputStreamAt(0))
  {
    DataWriter writer = new DataWriter(oStream);
    writer.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
    writer.WriteBytes(buffer);
    await writer.StoreAsync();
  }//write to folder
}