在我的应用程序中,我创建了一个类SerializableBitmapImage,它显示默认图像,而另一个图像从Internet下载。它还允许将下载的图像序列化为字节数组,因此不需要在每次应用程序启动时下载图像。 我目前在“Card”类中有一个SerializableBitmapImage,它在卡数据完成下载时保存:
var resp = await AppData.API.GetCards();
if (resp != null)
{
if (AppData.CardsData == null)
AppData.CardsData = new CardsData();
AppData.CardsData.Update(resp);
AppData.SaveCards();
FillCards();
}
但是,有时SerializableBitmapImage中的图像在调用AppData.SaveCards()时没有完成下载,导致图像无法保存。 所以,我正在寻找一种延迟保存的方法,直到下载图像为止。现在,我正在下载SerializableBitmapImage的构造函数中的图像,如下所示:
Image = new BitmapImage(defaultUri); //set to default while downloading
BitmapImage img = new BitmapImage { CreateOptions = BitmapCreateOptions.None };
img.ImageOpened += (sender, e) => //download successful, set Image to downloaded image
{
Image = sender as BitmapImage;
NotifyPropertyChanged("Image");
};
img.UriSource = downloadUri; //download the image
我在SerializableBitmapImage中创建了一个Task来等待图像完成,但我不确定它是否以健康的方式完成它的工作。
public async Task WaitForImageDownload()
{
while (Image == null || Image.UriSource.OriginalString == "Assets/MainPage/DefaultCard.png")
await Task.Delay(100); //check again if completed in 100ms
}
然后,在AppData.SaveCards()中,我等待所有图像下载后再保存卡片:
Task[] tasks = new Task[CardsData.Count];
for (int i = 0; i < CardsData.Count; i++)
tasks[i] = CardsData[i].CardImage.WaitForImageDownload();
await Task.WhenAll(tasks);
这是等待无法完成的操作的正确方法吗?或者,有没有办法强制图像立即下载? 谢谢你的帮助! 埃利奥特
答案 0 :(得分:6)
你很亲密。当然,每次你忙着等待警报都应该响起:
while (Image == null || Image.UriSource.OriginalString == "Assets/MainPage/DefaultCard.png")
await Task.Delay(100); //check again if completed in 100ms
那不完美。这样可以工作,但是你不必要地启动CPU,并引入了用户可能感觉到的延迟。最好只唤醒你正在等待的条件是真的。让图像通知您:
public async Task WaitForImageDownload()
{
var tcs = new TaskCompletionSource<bool>();
image.ImageOpened += (o, e) =>;
{
tcs.SetResult(true);
};
image.ImageFailed += (o, e) =>;
{
tcs.SetResult(false);
};
//set the source after the events have been attached
//or, check whether the image has been loaded already and only
//attach if it has
image.SetSource(TODO);
await tcs.Task;
}
(更好的是等待辅助方法。)
您对Task.WhenAll
的使用是一件好事。
或者,有没有办法强制图像立即下载?
从字面上回答:当然不是,这会违反物理学。 (我不知道你的意思是什么......)