加载时列表视图太慢

本文关键字:视图 列表 加载 | 更新日期: 2023-09-27 18:37:22

我正在用 1286 条记录填充列表视图,大约需要 34 秒。 我在互联网上搜索并找到了这个

 private void PopulateListViewWithCables(List<Cable> cables)
    {
        listView1.BeginUpdate();
        listView1.Items.Clear();
        System.Diagnostics.Stopwatch myStopWatch = new System.Diagnostics.Stopwatch();
        myStopWatch.Start(); 
        AddItemsToListView(cables);
        myStopWatch.Stop();
        string str;
        str = myStopWatch.Elapsed.Seconds.ToString();
        string s = str;
        listView1.EndUpdate();
    }

    private void AddItemsToListView(List<Cable> cables)
    {
        //Add to an ArrayList first because AddRange is a lot faster
        //than Add when dealing with lots of elements.
        //Also, there is no need to turn off the sorter when adding
        //all the elements at once
        ArrayList listItems = new ArrayList();
        foreach (Cable cable in cables)
        {
            // The if statement can be removed if all items in
            // MyDataClassCollection should be added to the ListView.               
            listItems.Add(CreateListViewItem(GetCableNavigation(cable)));
        }
        // Adds the items to the ListView
        listView1.Items.AddRange(
        (ListViewItem[])listItems.ToArray(typeof(ListViewItem)));
    }
    // Generate a listviewitem by using the myDataItem instance.
    private static ListViewItem CreateListViewItem(Cable cable)
    {
        ListViewItem item = new ListViewItem(
        new string[]
    {
    cable.Id.ToString(),
       cable.Item.ToString(),
       cable.GeneralFormat + cable.TagNo.ToString() + cable.EndString,
       cable.FromBay + cable.FromPanel, 
       cable.ToBay + cable.ToPanel,
       cable.CableProperty.Catalogue.Type,
       cable.CableProperty.Catalogue.CoreSize,
       cable.CableProperty.CableApplication.Application, 
       cable.CableRevision,
       cable.MinRequestCore.ToString(), 
       cable.Route, 
       cable.Distance.ToString(),
       ((CableStatusEnum)cable.Status).ToString(),
       cable.CableProperty.ProjectId.ToString(), 
       cable.CablePropertyId.ToString(),
       cable.TagNo.ToString(), 
       cable.GeneralFormat,
       cable.Length.ToString(), 
       cable.EndString, 
       cable.User.LastName, 
       cable.EditedOn.ToString()                
   });          
        return item;
    }
   private Cable GetCableNavigation(Cable cable)
    {
        CurrentInfo currentInfo = CurrentInfo.RecGetSingle();
        if (cable.CableProperty == null || cable.User == null)
        {
            using (CableServiceClient client = new CableServiceClient())
            {
                SearchElement[] criteria = new SearchElement[] { new SearchElement { Comparison = "=", FieldName = "Id", FieldValue = cable.Id, LogicalOperator = "" } };
                cable = client.GetCables(criteria, null, "CableProperty,CableProperty.Catalogue,CableProperty.CableApplication,User").SingleOrDefault();
                client.Close();
            }
        }
        return cable;
    }

我可以将加载时间减少到 29 秒,但对于 1286 条记录来说仍然太多了,如何减少加载数据的时间?

谢谢

加载时列表视图太慢

假设这是一个System.Windows.Forms.ListView,你应该看看虚拟化。使用虚拟化将自动为您延迟加载列表视图项,从而减少内存使用量并缩短响应时间。

我认为大多数时候您的代码都在创建服务客户端并从中查询数据。我建议您拆分数据加载(您可以在后台线程中执行此操作)和数据显示操作。还要考虑重用单个服务客户端实例。

像这样:

private void AddItemsToListView(List<Cable> cables)
{
    var items = GetCableNaviagations(cables)
                   .Select(CreateListViewItem)                       
                   .ToArray();
    listView1.Items.AddRange(items);
}
// consider to do data retrieving in background thread
private IEnumerable<Cable> GetCableNaviagations(IEnumerable<Cable> cables)
{
   var arg = "CableProperty,CableProperty.Catalogue,CableProperty.CableApplication,User";
   using (CableServiceClient client = new CableServiceClient())
   {
        foreach(var cable in cables)
        {
           var criteria = new SearchElement[] { 
              new SearchElement { 
                   Comparison = "=", 
                   FieldName = "Id", 
                   FieldValue = cable.Id, 
                   LogicalOperator = ""      
              } };
           yield return client.GetCables(criteria, null, arg).SingleOrDefault();
        }
        client.Close();
    }
}

它不会改变数据检索的时间,但在列表视图的"加载"阶段可能会有所帮助。创建一个返回"ListViewItem[]"的方法,并使用 Yield 返回:

private void PopulateListViewWithCables(List<Cable> cables)
{
    listView1.BeginUpdate();
    listView1.Items.Clear();
    System.Diagnostics.Stopwatch myStopWatch = new System.Diagnostics.Stopwatch();
    myStopWatch.Start();         
    foreach (listitem i in AddItemsToListView(cables))
    {
            cables.Add(i);
    }
    AddItemsToListView(cables);
    myStopWatch.Stop();
    string str;
    str = myStopWatch.Elapsed.Seconds.ToString();
    string s = str;
    listView1.EndUpdate();
}

private IEnumerable<ListViewItem> AddItemsToListView(List<Cable> cables)
{
    foreach (Cable cable in cables)
    {        
        yield return(CreateListViewItem(GetCableNavigation(cable)));
    }
}

我写它时没有检查它是否编译。