我的图像加载阻塞了UI线程时出现问题,因此我的网格视图在我的Windows应用商店中没有响应。
我想要做的是使gridview中的图像在我的视图模型中绑定到图像属性。 image属性的值由async方法设置。当app启动时,它会加载所有对象,但不会加载实际的图像数据。当UI虚拟化开始并且通过绑定到xaml中的图像控件的图像属性请求图像数据时,将加载图像数据。
所有这些都是在一个可观察的集合中完成的。
以下是一些代码:
private ImageSource _image = null;
private String _imagePath = null;
public ImageSource Image
{
get
{
SetImageFromStorageFile().ContinueWith(OnAsyncFail, TaskContinuationOptions.OnlyOnFaulted);
return this._image;
}
}
private async Task SetImageFromStorageFile()
{
this.IsLoading = true;
if (this._image == null && this._imagePath != null)
{
this._image = await BitmapLoader.GetPreviewImageFromStorageFile(this.StorageFile); //getting the actual data here
this.OnPropertyChanged("Image");
}
this.IsLoading = false;
}
除了UI在访问图像数据时没有响应时,这一切都正常。
正如您所看到的,我正在从属性调用异步方法,我只是重用我从其他地方调用的代码。当从其他地方调用时,我可以使用等待,并且UI是响应的。问题是,当使用gridviews UI虚拟化时,我不知道如何在不阻塞UI的情况下运行此异步方法,因为属性不可能运行异步(据我所知)。
所以我只想让gridview运行这个属性(或方法)async而不是sync,但不知道怎么做。
请帮助:)
答案 0 :(得分:1)
private ImageSource _image = null;
private String _imagePath = null;
public ImageSource Image
{
get
{
if (_image != null)
return _image;
if (_imagePath != null && !IsLoading)
SetImageFromStorageFile();
return null;
}
}
private async void SetImageFromStorageFile()
{
if (this.IsLoading || this._image != null || this._imagePath == null)
return;
this.IsLoading = true;
try
{
this._image = await BitmapLoader.GetPreviewImageFromStorageFile(this.StorageFile); //getting the actual data here
this.IsLoading = false;
this.OnPropertyChanged("Image");
}
catch
{
OnAsyncFail();
}
}
答案 1 :(得分:0)
无论您选择何种策略,都需要先返回一些内容并稍后填写。这是一个在vanilla WinRT页面中测试过的样本;您可以将其复制到名为Image
的{{1}}和名为image
的{{1}}的网页上进行复制。这可以放在TextBlock
或其他合适的位置。
status
我“返回”的东西是OnNavigatedTo
,它是BitmapImage imgsrc = new BitmapImage();
Task.Run(async () =>
{
await Task.Delay(10000);
await this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,
new Windows.UI.Core.DispatchedHandler(() =>
{
imgsrc.UriSource = new Uri("http://www.gratuit-en-ligne.com/telecharger-gratuit-en-ligne/telecharger-image-wallpaper-gratuit/image-wallpaper-animaux/img/images/image-wallpaper-animaux-autruche.jpg");
}));
});
image.Source = imgsrc;
status.Text = "Done";
的子类,所以它接近你想要使用的东西。 BitmapImage
只是为了在启动和图像填充之间引入明显的延迟,这样您就可以看到状态文本在图像加载之前设置好了。
要使您的样本能够正常运行,您需要在属性中创建(或访问)ImageSource
并立即返回,而不必等待它被填充。然后,您开始一个分配实际源数据的后台任务。
实际的因果关系链可能与我在此处显示的不同。例如,您可以从预先创建的集合中访问ImageSource。这将允许您在调用属性之前开始加载图像。但听起来这将是一个让你朝着正确的方向前进的开始。