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
}
答案 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
}