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

C# 是否可以在后台线程中填充ObjectListView?,c#,multithreading,winforms,backgroundworker,objectlistview,C#,Multithreading,Winforms,Backgroundworker,Objectlistview,我有一个应用程序,其中我向列表视图添加了数千项。此操作可能需要一段时间,但对于应用程序来说,这很好。但是,我仍然希望在填充列表时运行一个字幕进度条,以便用户可以看到正在发生的事情。进度条会锁定,因为UI线程正忙于添加项目 我尝试从后台工作程序中填充listview控件,但进度条仍被锁定。这让我明白,由于列表控件位于UI线程中,因此从后台工作程序填充它实际上不会改变任何东西 在这种情况下,有没有办法让进度条仍在运行 我想知道是否有可能让进度条在另一个线程中运行,但是我不知道怎么做,或者是否有可能

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

我尝试从后台工作程序中填充listview控件,但进度条仍被锁定。这让我明白,由于列表控件位于UI线程中,因此从后台工作程序填充它实际上不会改变任何东西

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

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

下面是我要说明的代码(添加2200个对象):


我也尝试过使用
BeginUpdate()
EndUpdate()
方法,但没有明显的效果(我认为它也会暂停并恢复布局)

多亏了您在评论中给我的指针,我才能够在填充列表时确定加载延迟:这不是由于列表控件本身造成的。无论何时将项目添加到列表中,都会访问要在列中显示的属性(如预期的那样)。但是,其中一些属性需要从数据库和磁盘额外加载数据

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

举例说明:

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.";
}

尝试使用
dispatcher
更新
listview
数据源。您是否尝试过在填充控件之前通过调用挂起/恢复布局,以及在添加所有项之后通过调用
listview1.ResumeLayout()
挂起/恢复布局?是否在添加项之前调用listview.BeginUpdate?也让我们了解“几千”在实数中的含义;“几个”对我来说意味着2000到5000,但对你来说可能更高一个数量级。替代方法:在虚拟模式下管理
ListView
。您管理数据(在使用它填充ListView之后,您可能已经拥有了这些数据!),并在需要显示数据时响应框架对其需要显示的数据的回调。它通常非常快,并且不会产生预填充ListView的开销。是否使用第三方类?在这种情况下,您可能应该在问题中添加标签。
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.";
}