1

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

4 回答 4

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
}
于 2012-10-25T13:02:56.473 回答
1

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

于 2012-10-24T05:38:45.963 回答
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;

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

为您辩护:对于使用 WinRT 类型的“概念证明”应用程序或桌面应用程序(引用适当的 .winmd 文件),同步调用异步代码可能是可以的。

于 2012-10-24T08:03:37.190 回答
1

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

于 2012-10-24T07:10:29.263 回答