我已经使用过很多 BackgroundWorkers,但我以前从未遇到过这个问题。我的程序分析逻辑分析仪的输出,生成数据包,其中有数千个。为了防止在我的表单中更新 ListView 出现太多延迟(我之前在发现每个表单时都会报告它,并且表单完全没有响应)我正在将 BackgroundWorker 内的数据包收集到一个通用列表中(List<Packet>)和然后报告当找到 n 个数量(当前为 250)时,或者发生异常时,或者当它完成时。
当我迭代 List<Packet> 时,我的回调中出现了问题,我收到 InvalidOperationException,并出现“集合已修改”错误。我没有触及 foreach 内的集合(我正在添加到另一个集合,但我认为这没有理由修改我正在迭代的集合 - 加上注释它并不能解决问题。)我已经甚至尝试锁定 e.UserState,将 e.UserState 存储到本地范围 List<Packet> 并锁定它,似乎没有任何效果。
这是我的回调方法的代码:
void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar.Value = e.ProgressPercentage;
packetsListView.SuspendLayout();
lock ((List<Packet>)e.UserState)
{
foreach (Packet packet in (List<Packet>)e.UserState)
{
packets.Add(packet);
ListViewItem item = new ListViewItem(string.Format("{0}ns", Math.Round(packet.StartSampleNumber * 41.666667)));
item.Tag = packet;
item.SubItems.Add(new ListViewItem.ListViewSubItem(item, packet.Description));
packetsListView.Items.Add(item);
}
}
packetsListView.ResumeLayout();
statusLabel.Text = string.Format("Analyzing...found {0} {1}", packetsListView.Items.Count, packetsListView.Items.Count == 1 ? "packet" : "packets");
}