BackgroundWorker 从循环中执行 UI 更新

2023-12-15

  • 我正在 BackgroundWorker 的 DoWork 内循环创建 ViewModel 对象
  • 我报告每次迭代的进度,将新对象作为参数传递以由 ProgressChanged 处理程序(它是 UI 线程的朋友)检索
  • 在该处理程序中,对象被添加到 ObservableCollection 中,并绑定了 ListBox。

我的 ViewModel 类包含两个字符串属性(Filename 和 ThumbnailPath),其 DataTemplate 包含绑定到这些属性的 Label 和 Image。

void bw_DoWork (object sender, DoWorkEventArgs e) {
   List<string> files = e.Argument as List<string>;
   FileInfo fi; int percent;
   for (int i = 0; i < files.Count; i++) {
      FileViewModel newItem = new FileViewModel(files[i]);
      fi = new FileInfo(files[i]);
      percent = i / files.Count * 100;
      bwImportBrowserItems.ReportProgress(percent, newItem);
   }
}

void bw_ProgressChanged (object sender, ProgressChangedEventArgs e) {
    this.observableCollection.Add(e.UserState as FileViewModel);
}

典型数量的项目 (30-50) 的典型行为:UI 冻结约 2-3 秒;显示大约一半的项目; UI 再次冻结的时间较短,然后添加其余部分。

现在我明白,从循环中调用 UI 更新并不是最好的主意 - 我认为调用如此频繁,UI 没有时间响应它们,这就是为什么我们看到 UI “成组”更新,留下它在此期间没有反应。

我尝试添加Thread.Sleep(500)作为循环的最后一行。这帮助我说明一切都按其应有的方式进行,因为随着经济放缓,项目被一个接一个地很好地添加没有任何无反应。

所以我尝试了不同的睡眠值定居于Thread.Sleep(25).这并不理想,但完全可以接受,并且非常接近它应有的样子。

我想问 Thread.Sleep 是否是一种常见的解决方法在这种情况下,以及人们在这种情况下采用的一般解决方案是什么:从后台循环更新 UI 集合,而不会出现任何无响应。 我也提出了一些想法,非常感谢您的评论。

我能想到的想法:

  1. 不要经常报告进度 - 将其限制为 10 次,或每 10 次 新东西。
  2. 不要循环进行。创建需要的项目列表 创建的。在 DoWork 主体中,从列表中出列一项, 实例化并返回 ViewModel 实例。在 RonWorkerCompleted 上, 更新 UI,检查我们的列表是否为空,如果不是, 再次运行WorkerAsync。

如果 Thread.Sleep 是此类情况下的常见解决方法

将其视为最后的手段。您正在增加总处理时间(而不是 CPU 负载)。

1) 不要太频繁地报告进度 - 将其限制为 10 次,或每 10 个新项目。

这是基本的想法。收集新项目并通过 ReportProgess 发送列表。调整列表的大小。

2)不要循环执行。

可能,但每个 Bgw 的 1 项看起来要慢得多。它甚至可能表现出相同的症状。

3)通过ConcurrentQueue解耦。您可以让 DoWork 填充队列,而 Dispatcher.Timer 可以清空它。还尝试使用该计时器处理批次。您可以调整计时器的优先级和批量大小。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BackgroundWorker 从循环中执行 UI 更新 的相关文章

  • 如何使用MemoryCache代替Timer来触发一个方法?

    以下方法通过等待已运行操作的结果来处理并发请求 对数据的请求可能会使用相同 不同的凭据同时出现 对于每组唯一的凭据 最多可以有一个GetCurrentInternal呼叫正在进行中 当准备就绪时 该呼叫的结果将返回给所有排队的服务员 pri
  • C++ 中本地类中的静态成员变量?

    我知道我们不能宣布static本地类中的成员变量 但其原因尚不清楚 那么请问有人可以解释一下吗 另外 为什么我们不能访问非static函数内部定义的变量 内部已经定义了局部类 直接在局部类成员函数中 在下面给出的代码中 int main i
  • 为 Visual Studio 2013 编译 Tesseract

    我正在尝试使用tesseract在 Visual Studio 2013 中 我在链接器 gt 输入 不是 libtesseract302 static lib 中使用 libtesseract302 lib 一切都正常 并且已编译并运行
  • XamlReader.Load 在后台线程中。是否可以?

    WPF 应用程序具有从单独的文件加载用户控件的操作 使用XamlReader Load method StreamReader mysr new StreamReader pathToFile DependencyObject rootOb
  • 如何访问另一个窗体上的ListView控件

    当单击与 ListView 所在表单不同的表单中的按钮时 我试图填充 ListView 我在 Form1 中创建了一个方法以在 Form2 中使用 并将参数传递给 Form1 中的方法 然后填充 ListView 当我调试时 我得到了传递的
  • 生成(非常)大的非重复整数序列而不进行预洗牌

    背景 我编写了一个简单的媒体客户端 服务器 我想生成一个不明显的时间值 随从客户端到服务器的每个命令一起发送 时间戳中将包含相当多的数据 纳秒分辨率 即使它不是真正准确 因为现代操作系统中计时器采样的限制 等 我想做的 在 Linux 上
  • 未经许可更改内存值

    我有一个二维数组 当我第一次打印数组的数据时 日期打印正确 但其他时候 array last i 的数据从 i 0 到 last 1 显然是一个逻辑错误 但我不明白原因 因为我复制并粘贴了 for 语句 那么 C 更改数据吗 I use g
  • 如何使用 watin 中的 FileUploadDialogHandler 访问文件上传对话框

    我正在使用 IE8 和 watin 并尝试通过我的网页测试上传文件 我不能简单地使用 set 方法设置上传文件 例如 ie FileUpload Find ById someId Set C Desktop image jpg 因为上传文本
  • 如何使用 Mongodb C# 驱动程序连接多个集合

    我需要将 3 个集合与多个集合合并在一起 lookup我在 C 驱动程序中尝试过 它允许我 lookup用户采集但无法执行秒 lookup用于设置集合 有人可以帮忙吗 db Transactions aggregate lookup fro
  • 等待线程完成

    private void button1 Click object sender EventArgs e for int i 0 i lt 15 i Thread nova new Thread Method nova Start list
  • HttpWebRequest 在第二次调用时超时

    为什么以下代码在第二次 及后续 运行时超时 代码挂在 using Stream objStream request GetResponse GetResponseStream 然后引发 WebException 表示请求已超时 我已经尝试过
  • 如何从main方法调用业务对象类?

    我已将代码分为业务对象 访问层 如下所示 void Main Business object public class ExpenseBO public void MakeExpense ExpensePayload payload var
  • (de)从 CSV 序列化为对象(或者最好是类型对象的列表)

    我是一名 C 程序员 试图学习 C 似乎有一些内置的对象序列化 但我在这里有点不知所措 我被要求将测试数据从 CSV 文件加载到对象集合中 CSV 比 xml 更受青睐 因为它更简单且更易于人类阅读 我们正在创建测试数据来运行单元测试 该集
  • 用于 C# 的 TripleDES IV?

    所以当我说这样的话 TripleDES tripledes TripleDES Create Rfc2898DeriveBytes pdb new Rfc2898DeriveBytes password plain tripledes Ke
  • 有没有办法强制显示工具提示?

    我有一个验证字段的方法 如果无法验证 该字段将被清除并标记为红色 我还希望在框上方弹出一个工具提示 并向用户显示该值无效的消息 有没有办法做到这一点 并且可以控制工具提示显示的时间 我怎样才能让它自己弹出而不是鼠标悬停时弹出 If the
  • 编译时“strlen()”有效吗?

    有时需要将字符串的长度与常量进行比较 例如 if line length gt 2 Do something 但我试图避免在代码中使用 魔法 常量 通常我使用这样的代码 if line length gt strlen Do somethi
  • 英特尔 Pin 与 C++14

    问题 我有一些关于在 C 14 或其他 C 版本中使用英特尔 Pin 的问题 使用较新版本从较旧的 C 编译代码很少会出现任何问题 但由于 Intel Pin 是操作指令级别的 如果我使用 C 11 或 C 14 编译它 是否会出现任何不良
  • 如何将 Roslyn 语义模型返回的类型符号名称与 Mono.Cecil 返回的类型符号名称相匹配?

    我有以下代码 var paramDeclType m semanticModel GetTypeInfo paramDecl Type Type Where paramDeclType ToString returns System Col
  • 当另一个线程可能设置共享布尔标志(最多一次)时,是否可以读取共享布尔标志而不锁定它?

    我希望我的线程能够更优雅地关闭 因此我尝试实现一个简单的信号机制 我不认为我想要一个完全事件驱动的线程 所以我有一个工作人员有一种方法可以使用关键部分优雅地停止它Monitor 相当于C lock我相信 绘图线程 h class Drawi
  • 如何正确使用 std::condition_variable?

    我很困惑conditions variables以及如何 安全 使用它们 在我的应用程序中 我有一个创建 gui 线程的类 但是当 gui 是由 gui 线程构造时 主线程需要等待 情况与下面的函数相同 主线程创建互斥体 锁和conditi

随机推荐

  • .NET 中不同线程之间共享的列表

    我在一个类中有一个静态列表 它将由不同的线程访问 每个线程从列表中添加 读取和删除自己的唯一项目 我想知道我是否必须担心使这个变量线程安全 因为即使同一个 List 对象在线程之间共享 它们也只会修改自己的唯一项目 你肯定必须通过以下方式实
  • 雷达动画安卓

    所以事情就是这样 我正在监视某些距离 并且我想将它们显示在雷达动画中 基础雷达图像是这样的像这样 不完全是 其中每个圆圈表示一个距离范围 这个想法是随着距离的变化 点向圆圈移动 我最初的方法是对同一雷达制作不同的图像 每个圆圈上都有一个点
  • 如何部署混合 C++/Java (JNI) 应用程序?

    tl dr C 插件需要调用 Java jar 库 如何将其部署给用户而不让用户太头疼 我正在为 Qt 应用程序编写 Qt 插件 该插件需要调用现有的 Java 库 这需要跨平台 Win Mac Linux 和架构 32 位和 64 位 I
  • MongoDB 修复命令失败

    以前我的磁盘空间不足 mongodb 停止工作 然后我增加了磁盘大小 但 mongodb 没有开始工作 虽然我启用了日记功能 但我执行了以下命令sudo u mongodb mongod dbpath var lib mongodb rep
  • 使用正则表达式在 bash 中搜索和替换

    我看过这个例子 hello ho02123ware38384you443d34o3434ingtod38384day echo hello 0 9 其语法如下 variable pattern replacement 不幸的是pattern
  • 为什么0.1有时能准确打印,有时却不能?

    I run print 0 1 print 0 2 print 0 3 print 0 4 print 0 5 print 0 5 0 4 print 0 4 0 3 print 0 3 0 2 print 0 2 0 1 表明 0 1 0
  • Capistrano 损坏的 Gemfile.lock 错误

    我正在尝试使用 Capistrano 部署我的应用程序 但收到此错误 Your Gemfile lock is corrupt The following gem is missing from the DEPENDENCIES secti
  • 如何识别显示器的数量、位置或分辨率何时发生变化? [复制]

    这个问题在这里已经有答案了 我正在构建一些需要检测监视器配置何时发生变化的东西 这包括添加 删除显示器 移动显示器位置 与主屏幕相比 或显示器分辨率发生变化 最理想的方法是捕获一些 Windows 消息 如果有 这些消息在此类事件发生时会被
  • 无法使用数据透视表制定查询来组合单行中的不同行值

    下面是实际的表格 In the table above 1 FEID is the examination ID which remains same for one exam like ist semester examination o
  • Jquery 根据其子元素之一的值查找 XML 元素

    我正在开发一个简单的 XML 电话簿应用程序来学习 JQuery 但我不知道如何执行以下操作 当用户在文本框中输入联系人的名字时 我想查找该人的完整记录 XML 看起来像这样
  • 使用Spring配置抽象工厂的实现类

    对于我的应用程序 我有一个Scale接口和实现该接口的多个类 例如NormalizedScale LogScale等等 在我的一项服务中 我需要创建许多 Scale 并且我想使用 Spring 来定义它应该创建 Scale 的哪个实现 我将
  • 当我从 sagemaker 端点获得预测时,端点会做什么?

    在 sagemaker 中 文档讨论了需要具有 4 个特定函数的推理脚本 当我们得到预测时 Python SDK 会向端点发送请求 然后推理脚本运行 但我找不到 SDK 中运行推理脚本的位置 当我浏览 sdk 代码时Predictor pr
  • PHP echo before sleep功能,不起作用

    我希望在睡眠函数执行之前在浏览器中输出回显 每次 以下代码不起作用 set time limit 0 ob implicit flush 1 ob start echo Start br ob flush for i 0 i lt 10 i
  • Redux VS Context API [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我非常熟悉 Context API 我完成了 Redux 速成课程 它们对我来说 原则上 很相似 问题是 我应该关注哪一个 Context API 和 Redux 之间的主要优缺点是什么
  • 在 Spark Scala 中合并两个 RDD

    我有两个 RDD rdd1 字符串 字符串 key1 value11 key2 value12 key3 value13 rdd2 字符串 字符串 key2 value22 key3 value23 key4 value24 我需要使用 r
  • 使用标签时如何使用Onclick事件

    我有两个java类 and 两种布局对于两个班级来说 每个layout正在拥有一个button在里面 两个班级都在延长Activity 现在在我使用的第一个布局中include像这样标记
  • 使用 Web API 在 jqGrid 中添加/编辑/删除

    我是 jqGrid 的新手 需要一些关于表单添加 编辑 删除功能的帮助 目前还没有找到相关资源 我的网格在添加 编辑时显示弹出窗口 还在单击编辑时填充数据 但是我不确定应该使用什么 javascript 代码来调用 Web api 来发布
  • scanf("%c", &c) 和 scanf(" %c", &c) 之间的区别[重复]

    这个问题在这里已经有答案了 考虑以下 C 代码片段 include
  • 如何在 PyTorch 中打印模型摘要?

    如何在 PyTorch 中打印模型的摘要 如下所示model summary 在 Keras 中执行的操作 Model Summary Layer type Output Shape Param Connected to
  • BackgroundWorker 从循环中执行 UI 更新

    我正在 BackgroundWorker 的 DoWork 内循环创建 ViewModel 对象 我报告每次迭代的进度 将新对象作为参数传递以由 ProgressChanged 处理程序 它是 UI 线程的朋友 检索 在该处理程序中 对象被