3

我正在用 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 条记录来说仍然太多了,我怎样才能减少加载数据的时间?

谢谢

4

3 回答 3

2

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

就像是:

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();
    }
}
于 2013-10-29T13:08:25.380 回答
2

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

于 2013-10-29T13:08:39.847 回答
0

它不会改变数据检索的时间,但可以帮助列表视图的“加载”阶段。创建一个返回“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)));
    }

}

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

于 2013-10-29T13:34:49.583 回答