0

私は次のコードを持っています:

var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();

99%の時間は正常に動作しますが、次の場合を除いて、ときどきクラッシュします。

Collection was modified; enumeration operation may not execute

少しランダムに見えるので少し迷っています。これはメソッドの最初の行です。ラムダ式がこの例外をスローする原因は何ですか?

4

2 に答える 2

1

それは糸脱毛と関係があります。これはウェブサイトのコードのようです。.ToList()の実行中にそのプライベート変数がサイトにアクセスする別の人によって変更された場合、その例外が発生します。

解決策はスレッドセーフコレクションを使用することですが、これは最適ではありません。多くの人がコレクションを読み書きしている場合、一度に実行できるのは多かれ少なかれ1つだけだからです。

同様の問題が発生しましたが、列挙は重要ではありませんでした。スキップまたは重複しても問題がなかったため、変更されたかどうかを確認しない独自の列挙子を実装しました。

于 2012-10-11T21:19:24.917 に答える
1

_messagesToExecuteへのすべての参照の周りでlock()を使用する必要があるか、コレクションを内部でロックすることを処理するSystem.Collections.Concurrentから何かを使用することができます。

例えば

_messagesToExecute = new ConcurrentBag<TMessage>();

または、ロックを使用したい場合:

static readonly object m_lock = new object();

その後、リストを更新するたびに:

lock(m_lock){
  _messagesToExecute.Add(item);
}

そして、リストを引き出すとき:

lock(m_lock){
    var actionsToExecute = _messagesToExecute.Where(m => m.CanExecute).ToList();
}
于 2012-10-11T21:42:06.517 に答える