4

オブジェクトを値として含むディクショナリを反復処理しようとしています。

foreach (KeyValuePair<int, CMapPool_Entry> Entry in MapPool)
{
   this.SendConsoleMessage(Entry.Value.Map);
}

以下に、CMapPool_Entryのクラスを示します。

public class CMapPool_Entry
{
    public string Map;
    public string Mode;
    public int Rounds;
    public int Index;
    public int Votes;

    public bool Nominated;
    public string Nominator;

    public CMapPool_Entry(string map, string mode, int rounds, int index, string Nominator_LeaveEmptyStringIfNone)
    {
        this.Map = map;
        this.Mode = mode;
        this.Rounds = rounds;
        this.Index = index;

        // If Nominator isn't empty, set map to nominated
        if (Nominator_LeaveEmptyStringIfNone != "")
        {
            this.Nominated = true;
            this.Nominator = Nominator_LeaveEmptyStringIfNone;
        }
    }

    public void AddVote()
    {
        this.Votes++;
    }

    public void RemoveVote()
    {
        if (this.Votes > 0)
            this.Votes--;
    }
}

ここでは、SendConsoleMessageメソッドも確認できます。

    private void SendConsoleMessage(string message)
    {
        this.ExecuteCommand("procon.protected.pluginconsole.write", String.Format("{0}", message));
    }

私にはそれが機能するように見えますが、foreach内のディクショナリから値を編集すると、「コレクションが変更されました。列挙操作が実行されない可能性があります。」というエラーが発生する方法について読みました。

しかし、なぜこのエラーが発生するのですか?私は値を編集していません、私はそれらを正しく読んでいますか?代わりにCObjectがstringまたはintの場合は正常に機能しますが、オブジェクトの場合は問題が発生します。私は何を間違っているのですか、私は何をすべきですか?


編集:さらにデバッグした後、Entry.Keyを使用しても問題がないことに気付きましたが、Entry.Valueをタッチするとすぐにエラーが発生します。何らかの理由で、2つの異なるエラーがランダムに発生しました。

  1. コレクションが変更されました。列挙操作が実行されない可能性があります。」
  2. 「指定されたキーが辞書にありませんでした。」

何か案は?または、オブジェクトを値として辞書を列挙するだけでは機能しませんか?

4

2 に答える 2

4

誰もがコメントで示しているように、あなたはそれから読み込もうとしている間に別のスレッドで辞書を変更しています。あなたは次のように書くことによって辞書を「コピー」することをコメントに書きました:

Dictionary<int, CMapPool_Entry> MapPool = this.Votemap_MapPool;

これは辞書をコピーしませんが、への参照を作成しますVotemap_MapPoolMapPoolしたがってVotemap_MapPool、コードのどこかを変更すると、読み取り中にコレクションが変更されたというメッセージとともにMapPool例外が発生します。System.InvalidOperationException

辞書を実際にコピーするには、次のように書く必要があります。

Dictionary<int, CMapPool_Entry> MapPool = new Dictionary<int, CMapPool_Entry>(Votemap_MapPool);

Votemap_MapPoolこれにより、コンテンツとしてディクショナリの新しいインスタンスが実際に作成Votemap_MapPoolされ、変更されても変更さMapPoolれません。

于 2012-07-14T12:25:00.070 に答える
0

foreachの処理中にコレクションを変更することはできません(辞書もコレクションです)。

回避策:

using System.Linq;

foreach (CObject value in ExampleDictionary.Values.ToArray()) {
   this.SendConsoleMessage(value.SomeVariableInObject);
}
于 2012-07-14T11:15:17.600 に答える