这是我第一次来这里,我正在努力解决这个问题。 我有这段代码:
try
{
progressBar1.Maximum = lista.Items.Count;
lista.BeginUpdate();
for (int i = 0; lista.Items.Count > i; i++)
//for (int i = lista.Items.Count - 1; -1 < i; i--)
{
if (lista.Items[i].SubItems[1].Text.ToLower().Contains(Text) == false)
{
lista.Items[i].Remove();
}
progressBar1.Value = progressBar1.Value + 1;
}
lista.EndUpdate();
progressBar1.Value = 0;
}
catch (Exception errore)
{
txt_info.Text = "" + errore.Message;
progressBar1.Value = 0;
}
方法lista.items[i].remove
非常慢。
lista
是ListView
,我正在处理大于50,000行的日志文件。
反正是为了加快这个过程吗?
答案 0 :(得分:3)
我会采用不同的方法并使用LINQ,如下所示:
lista.Items = lista.Items.Where(x=>x.SubItems[1].Text.ToLower.Contains(Text)).AsParallel().ToList();
基本上,重建列表一次,而不是一遍又一遍地尝试删除单个项目。
答案 1 :(得分:3)
最简单的选择是使用列表自己的RemoveAll method。
list.RemoveAll(x => !x.SubItems[1].Text.ToLower().Contains(Text))
P.S。
您可能希望在实际比较中寻找速度增益。
如果您的要求适合,使用String.Compare
要快得多。如果您想检查子字符串,我建议您使用ToUpperInvariant
来处理不变性问题 - it's designed to be faster。
答案 2 :(得分:1)
ListViewItem[] allElements = new ListViewItem[listView1.Items.Count];
listView1.Items.CopyTo(allElements, 0);
List < ListViewItem > list = allElements.ToList();
list.RemoveAll(item => item.SubItems[1].Text.ToLower().Contains(TextToFind) == false);
listView1.BeginUpdate();
listView1.Clear();
listView1.Items.AddRange(list.ToArray());
listView1.EndUpdate();
第一个规则永远不会在for循环中更新列表。你的逻辑只会运行到列表的一半。我想这不是你想要的。
我已经看到即使在使用BeginUpdate和EndUpdate之后,操纵listview.items也非常慢。关键是在外部进行操作(在列表中),然后使用AddRange重新填充列表(比Add快得多)。
答案 3 :(得分:0)
你可以把它粘在后台工作者身上并让它自己做。因此,在此过程发生时,您的用户仍可以使用该程序。
答案 4 :(得分:0)
如果你在 for 循环中删除一个项目,你应该将计数器设置为 1,这样你就不会错过一个。因为你删除了 [i],[old i+1] 变成了 [new i](Items.Count 也减少了 1),你会错过检查 [new i]。
例如:
ListView.Items.Remove[i];
i--;
答案 5 :(得分:0)
列表的动态访问速度很慢,更适合迭代。我建议在列表视图之外操作数据(可能通过在遍历源集合时将要显示的行一次复制到一个临时列表中),然后在最后分配给列表视图。这可以在不同的线程上完成(以提高 UI 性能)并且不需要昂贵的查找。