Reputation: 1563
The StoreBitmapImage
is synchronous function to store bitmap images to disk. But when I compile, I get System.AggregateException
, what am I doing wrong?
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
}
Upvotes: 1
Views: 1137
Reputation: 456577
One of the primary guidelines of async
code is "async
all the way down"; in other words, don't block on async
code.
Keeping with this guideline, you should make your method 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
}
Upvotes: 1
Reputation: 3023
You are trying to invoke GetResults on the IAsyncOperation object you get as the result of invoking an async method. That will fail in most cases since the async operation did not complete when the async method returns. The AggregateException you get is probably the result of trying to get the result to early. You could use following code to invoke an async method synchronously:
Task<StorageFile> task = folder.CreateFileAsync(fileName,
CreationCollisionOption.ReplaceExisting).AsTask();
// Read the result which will synchronously wait for the async operation
StorageFile file = task.Result;
Since invoking async code synchronously is not allowed by the Microsoft guidance for Windows Store apps and an application using such code would probably fail the certification a better solution would be to make your method async as well and invoke the async methods using await. That of course involves that your method itself is invoked using await. But if you design a new app this should not be a problem at all.
In your defence: Invoking async code synchronously is probably okay for "proof of concept" apps or Desktop apps that make use of WinRT types (referencing the appropriate .winmd files).
Upvotes: 1
Reputation: 16361
Trying to do such operation synchronosly is not a good practice. Saving a file from web can be done quite easy in WinRT, take a look at https://winrtxamltoolkit.codeplex.com/SourceControl/changeset/view/0657c67a93d5#WinRTXamlToolkit%2fNet%2fWebFile.cs.
Upvotes: 1
Reputation: 8852
System.AggregateException means there are multiple Exceptions
in your code. Can you explain what do you mean by How to treat an asynchronous method as a synchronous method?
Upvotes: 1