是否可以在后台线程中填充 ObjectListView?

Posted

技术标签:

【中文标题】是否可以在后台线程中填充 ObjectListView?【英文标题】:Is it possible to populate an ObjectListView in a background thread? 【发布时间】:2020-08-26 06:58:11 【问题描述】:

我有一个应用程序,我在其中将数千个项目添加到列表视图。此操作可能需要一段时间,但这对应用程序来说很好。但是,我仍然希望在填充列表时运行选取框进度条,以便用户可以看到正在发生的事情。 进度条锁定,因为 UI 线程正忙于添加项目。

尝试在后台工作人员中填充列表视图控件,但进度条仍被锁定。这让我明白,由于列表控件位于 UI 线程中,因此从后台工作人员填充它实际上并没有改变任何东西。

在这种情况下,有没有办法让进度条仍在运行?

我想知道是否可以让进度条在另一个线程中运行,但我不知道该怎么做,或者是否有可能。

这是我的代码来说明(添加 2200 个对象):

List.SuspendLayout();

StatusText.Text = "Populating the list...";
ProgressBar.Style = ProgressBarStyle.Marquee;

List.SetObjects(items);

List.ResumeLayout();

我也尝试使用BeginUpdate()EndUpdate() 方法,但没有明显效果(我假设它也会暂停和恢复布局)。

【问题讨论】:

尝试使用dispatcher更新listview数据源。 您是否尝试过在填充控件之前调用listview1.SuspendLayout() 以及在添加所有项目后调用listview1.ResumeLayout() 来暂停/恢复布局? 您在添加项目之前是否调用了 ListView.BeginUpdate?也让我们知道“几千”在实数中的含义; “几个”对我来说意味着 2 到 5 千,但对你来说可能更高一个数量级或数量级。 替代方法:在虚拟模式下管理ListView:ListView.VirtualMode Property。您管理数据(假设您已经拥有这些数据,因为您正在使用它来填充 ListView!)并在需要显示数据时响应来自框架的回调以获取它需要显示的数据。它通常非常快,并且不会产生预填充 ListView 的开销。 你使用ObjectListView第三方类吗?在这种情况下,您可能应该在您的问题中添加标签objectlistview。 【参考方案1】:

感谢您在 cmets 中给我的指示,我能够在填充列表时确定加载延迟:这不是由于列表控件本身造成的。每当将项目添加到列表中时,都会访问要在列中显示的属性 - 正如预期的那样。但是,其中一些属性需要从数据库和磁盘额外加载数据。

为了解决这个问题,我创建了一个单独的后台工作程序来初始化项目的内部数据缓存,然后再将它们添加到列表中。在此之后,实际显示列表最多只需要几秒钟。

举例说明:

private void PopulateList()

    StatusText.Text = "Populating the list...";

    // start the background worker
    PopulateListWorker.RunWorkerAsync();


private void Worker_PopulateList_DoWork(object sender, DoWorkEventArgs e)

    // run the data cache initialization


private void Worker_PopulateList_ProgressChanged(object sender, ProgressChangedEventArgs e)

    progressBar.Value = e.ProgressPercentage;


private void Worker_PopulateList_Completed(object sender, RunWorkerCompletedEventArgs e)

    List.SuspendLayout();
    List.SetObjects(items);
    List.ResumeLayout();

    progressBar.Value = 0;
    StatusText.Text = "All done.";

【讨论】:

以上是关于是否可以在后台线程中填充 ObjectListView?的主要内容,如果未能解决你的问题,请参考以下文章

是否自动在后台线程中将数据发布到 api

通过AsyncTask访问后台后得到的返回数据在Android端显示

在后台线程中运行处理程序消息

试图了解 iOS 中后台线程行为的幕后情况

Core Data,在后台线程中修改 NSManagedObject

在 ui 线程中执行委托(使用消息泵)