使用 WPF 在线程中加载图像

2023-12-07

我正在尝试制作一个列表框来显示来自互联网的图片。这些项目是通过将 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(使用前将#替换为@)

使用 WPF 在线程中加载图像 的相关文章

随机推荐

  • 无法从文件加载正确的信息

    这段代码的问题是它没有正确读取 txt 文件 我提供了 txt 文件的图像 同时还提供了它给我的当前输出 任何帮助都会受到欢迎 include
  • 迁移到 AutoMapper 5 - 循环引用

    我有一个System StackOverflowException当尝试在 AutoMapper 5 中映射以前在 AutoMapper 4 中工作的内容时 经过一番谷歌搜索后 我发现这是由循环引用 AutoMapper 文档说 以前 Au
  • 在 MEAN Stack 环境中使用 Passport.js 验证路由

    我无法使用 Passport js 保护管理面板的各个路由 用户注册正在运行 即使当我登录面板时 它也会成功重定向 但 req isAuthenticate 始终返回 false 值 因此 我无法访问管理面板内的路由 Codes 控制器 a
  • 具有依赖范围的嵌套模板

    在以下错误的上下文中 什么是依赖范围以及 typename 的含义是什么 make g std gnu 0x main cpp main cpp 18 10 error need typename before ptrModel
  • CodeIgniter 检查查询是否成功[重复]

    这个问题在这里已经有答案了 我在网上搜索了一下 大部分都建议使用num rows或类似的函数来检查 CodeIgniter 中的查询是否成功 但是我使用的是update功能 data array title gt title name gt
  • 谷歌地图地理编码器不如谷歌地图准确

    我有一个数据库 其中包含精确到建筑物级别的地址 当我手动将这些放入谷歌地图的搜索中时 谷歌地图发现它们没有问题 标记出现在正确的建筑物上方 但是 当我使用以下代码将这些相同的地址传递给 Google Maps API 地理编码器时 标记仅显
  • Node.js、MongoDB - 插入/更新多个文档并发送单个响应

    我正在尝试开发一种同步服务器 类似于 SVN 它在一个请求 JS 对象的 JSON 字符串化数组 中接受来自客户端的一个或多个文档 JSON 字符串 将它们插入 更新到 mongodb 中并发送一个响应 这是一个 JSON 字符串 包含每个
  • 您可以帮助修改查询或其他查询以获得预期结果吗

    我尝试了很多方法但没有得到预期的结果 我怎样才能得到预期的结果 您可以下载数据库表结构从这里 SELECT IF o source id 1 online 0 TYPE MONTH date created AS monthvalue SU
  • 如何抑制 TCL 程序的输出消息?

    在我的 TCL 脚本中 我使用了几个没有源代码的过程 所有这些过程都会执行一些任务并输出大量消息 但我只想完成任务 并且想抑制这些消息 有没有办法做到这一点 例如 我想运行这样的程序 my proc arg1 arg2 arg3 并压制所有
  • Android libgdx 首选项不起作用

    可能是一个愚蠢的问题 但是我必须更改什么才能使此代码正常工作 package com hobogames WizardsDuel import com badlogic gdx Gdx import com badlogic gdx Pre
  • 没有参数的函数没有足够的参数

    我是 GO 新手 所以我想尝试开发一个小应用程序来帮助我管理一些旅行 我正在遵循这里找到的设计 sohamkamani com 我遇到了一些对我来说没有意义的错误 src trip manager handlers PersonHandle
  • 如果打开设备,QSerialPort 会导致程序停止(无限循环?)

    我想在串行设备上写入 不幸的是 我感觉 QSerialPort 在 Linux 下没有正确实现 与其他方法 python 相比 我有时会得到 当我尝试调用时程序挂起 serial open QIODevice ReadWrite 我正在使用
  • Java 方法注释如何与方法重写结合使用?

    我有一个家长班Parent和一个儿童班Child 定义如下 class Parent MyAnnotation hello void foo implementation irrelevant class Child extends Par
  • 在 TensorFlow 图中使用 if 条件

    在张量流 CIFAR 10 中tutorial in cifar10 inputs py第 174 行据说您应该随机化 random contrast 和 random brightness 操作的顺序 以获得更好的数据增强 为此 我首先想
  • bash,向前和向后查找最近的下一个值

    我有一个 data txt 文件 1 2 3 4 5 6 7 cat data txt 13 245 1323 10 1111 10 2222 60 1111 60 22222 13 133 2325 11 2222 11 333 61 2
  • scanf 和 fgets 的问题

    这是一项家庭作业 用于对某些给定的字符串进行排序 我提示用户输入他们想要排序的字符串数量scanf 根据该数字分配一个数组 然后使用以下命令获取字符串本身fgets 如果字符串的数量是硬编码的 那么一切都会正常工作 但是添加scanf让用户
  • 获取 XHR 响应(网络流量)并在 Katalon Studio 中解析它

    如何读取 XHR 响应并在 Katalon Studio 中解析它 我目前使用一种解决方法来测试我的应用程序的响应能力 我使用各种waitForElement 可见 可点击 存在 不可见 不可点击 不存在 命令 以测量各种元素的加载时间 我
  • onActivityResult() 在意外时间被调用

    在我的主要活动中 我有 Intent settings intent new Intent this SettingsActivity class settings intent putExtra SomeID some int start
  • 如何间接引用 grails GSP 模型变量,例如通过 .get(...)

    我正在使用 GSP 基于 MailService 插件发送电子邮件 sendMail 关闭通过 除其他外 body view model myModel 我知道我可以使用以下命令访问 myModel 地图的每个项目 itemName 在普惠
  • 使用 WPF 在线程中加载图像

    我正在尝试制作一个列表框来显示来自互联网的图片 这些项目是通过将 itemsource 绑定到包含图像 URL 和一些其他属性 标题 描述等 的模型来提供的 不幸的是 该列表的加载速度非常慢 因为 WPF 在显示列表之前尝试从 Web 下载