私は 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");
}