使用BackgroundWorker更新UI而不冻结...?

2024-06-26

我有以下代码用于从后台线程填充 ListView (DoWork 调用 PopulateThread 方法):

delegate void PopulateThreadCallBack(DoWorkEventArgs e);
private void PopulateThread(DoWorkEventArgs e)
{

    if (this.InvokeRequired)
    {
        PopulateThreadCallBack d = new PopulateThreadCallBack(this.PopulateThread);
        this.Invoke(d, new object[] { e });
    }
    else
    {

        // Ensure there is some data
        if (this.DataCollection == null)
        {
            return;
        }

        this.Hide();

        // Filter the collection based on the filters
        List<ServiceCallEntity> resultCollection = this.ApplyFilter();

        // Get the current Ids
        List<Guid> previousIdList = this.GetUniqueIdList(listView);
        List<Guid> usedIdList = new List<Guid>();

        foreach (ServiceCallEntity record in resultCollection)
        {

            if (e.Cancel)
            {
                this.Show();
                return;
            }
            else
            {

                // Get the top level entities
                UserEntity userEntity = IvdSession.Instance.Collection.GetEngineerEntity(record.UserId);
                AssetEntity assetEntity = IvdSession.Instance.Collection.GetAssetEntity(record.AssetId);
                SiteEntity siteEntity = IvdSession.Instance.Collection.GetSiteEntity(record.SiteId);
                FaultEntity faultEntity = IvdSession.Instance.Collection.GetFaultEntity(record.FaultId);

                if (siteEntity == null || userEntity == null || faultEntity == null)
                {
                    continue;
                }
                else
                {

                    // Get the linked entities
                    RegionEntity regionEntity = IvdSession.Instance.Collection.GetRegionEntity(siteEntity.RegionId);
                    StatusEntity statusEntity = IvdSession.Instance.Collection.GetStatusEntity(record.ServiceCallStatus.StatusId);

                    ListViewItem item = new ListViewItem(siteEntity.SiteName);
                    item.SubItems.Add(siteEntity.Address);
                    item.Tag = record;

                    item.SubItems.Add(regionEntity.Description);

                    // Handle if an Asset is involved
                    if (record.AssetId > 0)
                        item.SubItems.Add(assetEntity.AssetDisplay);
                    else
                        item.SubItems.Add("N/A");

                    item.SubItems.Add(faultEntity.Description);
                    item.SubItems.Add(userEntity.UserDisplay);

                    item.SubItems.Add("TODO: Claimed By");
                    item.SubItems.Add(record.DateTimeStamp.ToString());

                    IvdColourHelper.SetListViewItemColour(item, false);
                    this.PopulateItem(item, ref usedIdList);

                }

            }

        }

        // Clean up the grid
        this.CleanListView(previousIdList, usedIdList);

        // Only autosize when allowed and when there are some items in the ListView
        if (this.AllowAutoSize && listView.Items.Count > 0)
        {
            rsListView.AutoSizeColumns(listView);
            this.AllowAutoSize = false;
        }

        this.Show();

    }

}

不幸的是,这会导致 UI 在 foreach 中冻结...有没有什么方法可以更新/填充 ListView 而不会冻结主 UI?


A) 您可能不需要使用 this.Invoke 而是使用 this.BeginInvoke。 Invoke 会阻塞当前线程。

B)您不需要定义自己的委托,您可以使用 MethodInvoker

if(this.InvokeRequired) {
  this.BeginInvoke(new MethodInvoker(() => PopulateThread(e)));
  return;
}

干净多了:)

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

使用BackgroundWorker更新UI而不冻结...? 的相关文章

  • 获取当前用户的 NetworkCredential (C#)

    我正在尝试从控制台应用程序调用 Web 服务 并且我需要向客户端提供System Net NetworkCredential object 是否有可能创建一个NetworkCredential启动应用程序的用户的对象而不提示输入用户名 密码
  • 如何将 CroppedBitmap 转换为 BitmapImage

    我正在尝试将 CroppedBitmap 转换为 BitmapImage 编辑 不使用内存流 我尝试过直接转换它 似乎这不是一个选择 这应该没那么难 我正在尝试剪切 BitmapImage 的一部分 并创建一个仅包含新裁剪的 Bitmap
  • 如何从 std::vector 中删除元素而不调整其大小

    迭代器擦除 迭代器位置 迭代器擦除 首先是迭代器 迭代器最后 擦除元素 从向量中删除 容器可以是单个元素 位置 或一系列元素 第一个 最后一个 这有效地减少了向量 大小除以元素数量 删除 调用每个元素的 之前的析构函数 and remove
  • 外部剃刀视图看不到外部模型

    我对外部剃刀视图有疑问 在我的项目中 我有主 mvc Web 程序集和动态加载的外部类库程序集 来自 DB 及其自己的控制器 视图和模型 这些程序集在运行时不会直接引用和加载 我能够通过为控制器创建自定义控制器工厂 为视图创建自定义虚拟路径
  • 指向指针的指针和指向二维数组的指针之间的区别

    如果我有一个二维数组 B 定义为 int B 2 3 1 3 5 2 4 6 Is int p B与 一样int p 3 B int f B printf d f 1 gives 5作为输出 同时printf d f 给出 1 作为答案 为
  • 错误 C2065:'cout':未声明的标识符

    我正在处理我的编程作业的 驱动程序 部分 但我不断收到这个荒谬的错误 错误 C2065 cout 未声明的标识符 我什至尝试过使用std cout但我收到另一个错误 IntelliSense 命名空间 std 没有成员 cout 当我宣布u
  • 将标准库添加到C++ eclipse项目中

    一个 非常 新手 C 问题 有没有办法自动将标准库添加到 C eclipse 项目中 我安装了 CDT 主要功能插件 您可以手动添加 STL 标头的路径路径和符号 gt 包含选项卡 http help eclipse org galileo
  • 在 Windows 服务中使用 OleDb 从 Excel 读取数据?

    免责声明 我知道这是一种不好的做事方式 这是我们与客户的唯一选择 Problem 我们需要每隔 x 时间从 Excel 文件读取数据 数据通过第三方 Excel 插件不断变化 应用程序的环境是 Windows XP SP1 和 Net 2
  • MVVM 同步集合

    是否有一种标准化方法可以将 Model 对象集合与 C 和 WPF 中匹配的 ModelView 对象集合同步 我正在寻找某种类 可以使以下两个集合保持同步 假设我只有几个苹果 并且可以将它们全部保存在内存中 换句话说 我想确保如果我将 A
  • 使用私有构造函数的 C# 单元测试类?

    好吧 我刚刚收到一个作业 我必须对具有私有构造函数的类执行单元测试 现在 当所有方法也都是非静态时 我该如何在不初始化类的情况下进行单元测试 有什么方法可以对具有私有构造函数的类进行单元测试 无需反射 如果您无法将类公开 您仍然可以通过以下
  • 用于 C/C++ 的独立跨平台 (Windows/Linux) 文件压缩?

    我正在寻找一个 最好是小的 C 或 C 开源库 我可以将其包含在我的 MIT 许可项目中 托管在 google 代码上 我是一名业余爱好 C C 程序员 所以我并不那么先进 但我只知道为名为 SA MP 的应用程序 适用于 Windows
  • UWP - 绑定枚举差异

    我遇到了一个非常有趣的问题 假设 UWP 应用中有以下 XAML 页面内容
  • WPF MVVM后台打印数据绑定问题

    我正在使用 wpf mvvm 开发一个销售点应用程序 在交易生命周期的许多阶段 都会在后台打印收据 我已经使用其他示例在后台生成和打印收据 我正在后台打印一个 UserControl 一切看起来都很棒 然后 我为该控件创建了 ViewMod
  • 除法时的小数舍入误差 (C#)

    我基本上有四个数字 比如 100 200 300 400 我需要计算概率为 100 100 200 300 400 200 100 200 300 400 等等在 当我使用小数数据类型来存储这些概率时 由于舍入问题 它们不会达到 1 在不使
  • 如何通过 Excel 互操作对象自动调整列大小?

    下面是我用来将数据加载到 Excel 工作表中的代码 但我希望在加载数据后自动调整列的大小 有谁知道自动调整列大小的最佳方法 using Microsoft Office Interop public class ExportReport
  • 将 R 值传递给采用 L 值的函数时出现过载歧义

    我有 2 个重载函数 一个采用 L 值 另一个采用 R 值 目的是让该函数可以像这样调用 Obj obj foo obj OR foo Obj 所以 我写了2个重载函数 template
  • 如何进行平衡组捕获?

    假设我有这个文本输入 tes tR R abc aD mnoR xyz 我想提取 ff 输出 R abc R xyz D mnoR xyz R R abc aD mnoR xyz 目前 我只能使用平衡组方法提取组内的内容 如中所示msdn
  • 从不同的线程访问对象

    我有一个服务器类 它基本上等待来自客户端的连接 在该类中 我创建了一个 NetworkStream 对象 以便能够从客户端接收字节 由于 NetworkStream Read 方法不是异步的 这意味着它将等到从客户端读取字节才能继续执行类似
  • RC4 实现与 openssl 输出不匹配

    我的目标是在 C C 中实现 RC4 流密码 并确保它产生与使用时相同的输出openssl命令 按照伪代码维基百科 https en wikipedia org wiki RC4 该实现似乎有效 因为它可以加密和解密内容 但是 加密的输出与
  • Java中ThreadFactory的使用

    有人可以简要解释一下如何以及何时使用 ThreadFactory 吗 使用和不使用 ThreadFactory 的示例可能确实有助于理解差异 Thanks 这是一种可能的用法 假设您有一个ExecutorService它执行你的Runnab

随机推荐