Ari*_*l32 1 c# wpf multithreading image list
我正在尝试制作一个显示来自互联网图片的列表框.这些项目是通过将itemsource绑定到包含图像URL和其他一些属性(title,desc等等)的模型来提供的.
不幸的是,列表加载速度非常慢,因为WPF在显示列表之前尝试从Web下载所有图片,并使应用程序冻结15到25秒.
我已经读过我应该在另一个帖子中加载图片,但我不知道我应该在哪里做以及如何做?是否更好地直接在模型中加载所有图片(通过仅为此创建一个线程池 - 但问题是它不是模型/模型视图的真正部分)或者更好地创建一个将直接更新的后台线程列表何时有数据?
谢谢 !
简单的方法就是Binding.IsAsync像这样设置属性:
<Image ImageSource="{Binding propertyThatComputesImageSource, IsAsync=true}" />
Run Code Online (Sandbox Code Playgroud)
每次访问propertyThatComputesImageSource都将从ThreadPool线程完成.如果线程使用ImageCacheOptions.OnLoad创建图像,它将阻塞,直到加载图像.因此,UI将立即启动,图像将在后台加载,并在可用时显示.
Binding.IsAsync对于十个或二十个图像来说是一个很好的解决方案,但如果你有数百个图像并且加载延迟很长,那么它可能不是一个好的解决方案,因为你最终可能会有数百个线程.在这种情况下,直接使用ThreadPool将数据加载到数据绑定之外:
ThreadPool.QueueUserWorkItem((state) =>
{
foreach(var model in _models.ToArray())
model.ImageSource = LoadOneImage(model.ImageUrl);
});
Run Code Online (Sandbox Code Playgroud)
如果模型的属性是DependencyProperty,则可能需要使用Dispatcher.Invoke或两个扩展,因为无法从单独的线程访问它们.
这种技术可以扩展为产生固定数量的工作者来加载图像并打破它们之间的工作,从而发生多个图像下载,但是同时下载的数量是有限的,所以你最终不会有数百个线程.