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

このような操作を同期的に実行しようとするのは良い習慣ではありません。WinRTでは、Webからファイルを保存するのは非常に簡単です。https://winrtxamltoolkit.codeplex.com/SourceControl/changeset/view/0657c67a93d5#WinRTXamlToolkit%2fNet%2fWebFile.csを参照してください。

于 2012-10-24T07:10:29.263 に答える
1

asyncコードの主要なガイドラインの1つは、 「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;

非同期コードを同期的に呼び出すことは、Windows ストア アプリの Microsoft ガイダンスでは許可されておらず、そのようなコードを使用するアプリケーションはおそらく認証に失敗するため、より良い解決策は、メソッドも非同期にし、await を使用して非同期メソッドを呼び出すことです。もちろん、それには、メソッド自体が await を使用して呼び出されることが含まれます。しかし、新しいアプリを設計する場合、これはまったく問題にはなりません。

あなたの弁明: 非同期コードを同期的に呼び出すことは、"概念実証" アプリまたは WinRT 型を利用する (適切な .winmd ファイルを参照する) デスクトップ アプリではおそらく問題ありません。

于 2012-10-24T08:03:37.190 に答える