2012-10-24 5 views
1

StoreBitmapImage является синхронной функцией для хранения растровых изображений на диск. Но когда я компилирую, я получаю System.AggregateException, что я делаю неправильно?В Windows8, Как обрабатывать асинхронный метод как синхронный метод?

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 
    } 

ответ

1

System.AggregateException означает Есть несколько Exceptions в вашем коде. Можете ли вы объяснить, что вы подразумеваете под Как обрабатывать асинхронный метод как синхронный метод?

+0

Я прошу прощения за путаницу. – JohnyDgoode

1

Попытка выполнить такую ​​операцию синхронно не является хорошей практикой. Сохранение файла из Интернета можно сделать в WinRT довольно просто, посмотрите на https://winrtxamltoolkit.codeplex.com/SourceControl/changeset/view/0657c67a93d5#WinRTXamlToolkit%2fNet%2fWebFile.cs.

+0

Спасибо! не знал этого пути :) – JohnyDgoode

1

Вы пытаетесь вызвать GetResults в объекте IAsyncOperation, который вы получаете в результате вызова метода async. Это приведет к сбою в большинстве случаев, поскольку операция async не завершилась, когда метод async вернется. Исключение 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 Store и приложением с помощью такого кода, вероятно, не в состоянии к сертификации лучшим решения будет чтобы сделать ваш метод асинхронным, а также использовать методы async, используя ожидание. Конечно, это связано с тем, что ваш метод запускается с помощью await. Но если вы разрабатываете новое приложение, это не должно быть проблемой вообще.

В вашей защите: синхронно вызывать синхронный асинхронный код, вероятно, подходит для приложений «доказательство концепции» или для настольных приложений, использующих типы WinRT (ссылаясь на соответствующие файлы .winmd).

+0

Предполагаю, что если я использую «ожидание», компилятор немедленно перейдет к следующей строке. Я понимаю, что если я использую «ожидание», компилятор ждет обработки метода и продолжит следующую строку. И если я используйте метод GetResults, компилятор немедленно перейдет к следующей строке. Я ошибся. Спасибо много! – JohnyDgoode

+0

Добро пожаловать :-) –

+0

Я не мог использовать ваш пример. CreateFileAsync возвращает IAsyncOperation , а не задание Rui

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 
} 
+0

Я вижу, Большое спасибо! – JohnyDgoode

Смежные вопросы