我正在尝试制作一个列表框来显示来自互联网的图片。这些项目是通过将 itemsource 绑定到包含图像 URL 和一些其他属性(标题、描述等)的模型来提供的。
不幸的是,该列表的加载速度非常慢,因为 WPF 在显示列表之前尝试从 Web 下载所有图片,这会使应用程序冻结 15 到 25 秒。
我读过我应该在其他线程中加载图片,但我不知道应该在哪里以及如何加载图片?是否最好直接在模型中加载所有图片(通过为此创建一个线程池 - 但问题是它并不是模型/模型视图的真正一部分),还是创建一个直接更新的后台线程更好?列出何时有数据?
谢谢 !
最简单的方法就是只需设置Binding.IsAsync
像这样的属性:
<Image ImageSource="{Binding propertyThatComputesImageSource, IsAsync=true}" />
每次访问propertyThatComputesImageSource
将从 ThreadPool 线程完成。如果线程使用 ImageCacheOptions.OnLoad 创建图像,它将阻塞,直到图像加载完毕。因此,UI 将立即启动,图像将在后台加载并在可用时显示。
Binding.IsAsync
对于十个或二十个图像来说是一个很好的解决方案,但如果您有数百个图像并且加载延迟很长,则可能不是一个好的解决方案,因为您最终可能会使用数百个线程。在这种情况下,直接使用 ThreadPool 完全在数据绑定之外加载图像:
ThreadPool.QueueUserWorkItem((state) =>
{
foreach(var model in _models.ToArray())
model.ImageSource = LoadOneImage(model.ImageUrl);
});
如果模型的属性是 DependencyProperty,则可能需要使用一个或两个 Dispatcher.Invoke 进行扩展,因为无法从单独的线程访问它们。
这种技术可以扩展为产生固定数量的工作人员来加载图像并分解它们之间的工作,以便发生多个图像下载,但同时下载的数量是有限的,因此您最终不会有数百个线程。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)