是否可以在后台线程中填充 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?的主要内容,如果未能解决你的问题,请参考以下文章
通过AsyncTask访问后台后得到的返回数据在Android端显示