I've used BackgroundWorkers quite a bit, but I've never experienced this problem before. My program analyses the output from a logic analyser producing packets, of which there are thousands. To prevent too much delay updating the ListView in my form (I was previously reporting each one as it was found, and the form was completely unresponsive) I'm collecting the packets inside the BackgroundWorker in a generic list (List<Packet>) and then reporting that either when n amount are found (currently 250), or when an exception occurs, or when it completes.
The problem occurs in my callback when I'm iterating over the List<Packet> I get an InvalidOperationException, with the "Collection was modified" error. I'm not touching the collection inside the foreach (I'm adding to another collection, but I see no reason this could modify the collection I'm iterating over - plus commenting it out doesn't fix the problem.) I've even tried locking the e.UserState, storing the e.UserState into a local scope List<Packet> and locking that, nothing seems to work.
Here's the code for my callback method:
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");
}