2016-05-24 13 views
4

私は問題につまずいています。私が間違っていることについては何の手がかりもありません。私は数え切れないほどのものを試しましたが、何らかの理由でそれはうまく動作しません。私のメインループ:コードは辞書全体を反復処理していませんか?

static Dictionary<string, int> dict = new Dictionary<string, int>(); 

public static void IterateOverEachUser() 
{ 
    if (dict.Count > 0) { 
     foreach (KeyValuePair<string, int> item in dict.ToList()) 
     { 
      string userName = item.Key; 
      int amountLeft = item.Value; 
      if(amountLeft == 60) 
      { 
       Log(userName + " started!"); 
      } 
      Log(userName + amountLeft); 
      dict[userName] = dict[userName] - 1; 
      amountLeft = item.Value; 
      if(amountLeft == 0) 
      { 
       Log(userName + " ran out!"); 
      } 
     } 
    } 
} 

public static void AddUser(string User) 
{ 
    if (dict.ContainsKey(User)) 
    { 
     Log("User already exists."); 
    } 
    else 
    { 
     dict.Add(User,60); 
     Log("User has been added."); 
    } 
} 

私は5秒ごとにIterateOverEachUser()をループしています。メソッドを使用してユーザーを追加するとすべて問題ありませんが、2つ目の値を追加すると、その値は60に固定され、残りの値は固定されます。

これはなぜ起こるのですか?私はJavaからHashMapsを使用していますが、意図したとおりに動作する同じコードを使用しています。 (つまり、すべてのユーザーが繰り返し処理され、すべてのユーザーの値が1減算され、5秒ループでIterateOverEachUser()メソッドが再び呼び出されるまで停止します)。

ありがとうございます!

+4

私はdownvotedますが、私はどんな建設的な批判を得ることはありませんか?私の知る限り、私のコードは完璧に動作するでしょうか?私は自分のコードを投稿した、私は広範な研究をしたことを示した、私は自分の問題を説明し、私はコードが何を期待しているか説明する。これはdownvoteに値するものではありません.. imo –

+2

注意して、それをルーピングしながら辞書を変更しています。ほとんどの言語で、これは問題になる可能性があります –

+0

@HoàngLongご意見ありがとうございます!私はこれについても考えましたが、 ".ToList()"を追加しても問題は解決しません。また、これを実行して実行中に辞書を編集しなくても良い方法を知っていますか? –

答えて

4

amountLeft = item.Value;は、間違った値(古いもの)を生成します。

また、タイマーと静的リソースを使用して作業する場合は、lockを使用してスレッドセーフにする方がよいでしょう。

以下のテストコードは、私のために完璧に動作します:

static Dictionary<string, int> dict = new Dictionary<string, int>(); 
static object lockObject = new Object(); 

public static void IterateOverEachUser() 
{ 
    lock (lockObject) 
    { 
     if (dict.Count > 0) 
     { 
      foreach (KeyValuePair<string, int> item in dict.ToList()) 
      { 
       string userName = item.Key; 
       int amountLeft = item.Value; 
       if (amountLeft == 60) 
       { 
        Console.WriteLine(userName + " started!"); 
       } 
       Console.WriteLine(userName + amountLeft); 
       dict[userName] = dict[userName] - 1; 
       amountLeft = dict[userName]; 
       if (amountLeft == 0) 
       { 
        Console.WriteLine(userName + " ran out!"); 
       } 

       Console.WriteLine("User " + item.Key + " = " + amountLeft); 
      } 
     } 
    } 
} 

public static void AddUser(string User) 
{ 
    if (dict.ContainsKey(User)) 
    { 
     Console.WriteLine("User already exists."); 
    } 
    else 
    { 
     dict.Add(User, 60); 
     Console.WriteLine("User has been added."); 
    } 
} 

static void Main(string[] args) 
{ 

    AddUser("U1"); 
    AddUser("U2"); 

    int counter = 1; 
    System.Timers.Timer t1 = new System.Timers.Timer(); 
    t1.Interval = 5000; 
    t1.Elapsed += (oo, ee) => 
    { 
     IterateOverEachUser(); 

     if (counter++ == 5) 
      AddUser("U3"); 
    }; 

    t1.Start(); 

    Console.ReadKey(); 
} 

出力:

User has been added. 
User has been added. 
U1 started! 
U160 
User U1 = 59 
U2 started! 
U260 
User U2 = 59 
U159 
User U1 = 58 
U259 
User U2 = 58 
U158 
User U1 = 57 
U258 
User U2 = 57 
U157 
User U1 = 56 
U257 
User U2 = 56 
U156 
User U1 = 55 
U256 
User U2 = 55 
User has been added. 
U155 
User U1 = 54 
U255 
User U2 = 54 
U3 started! 
U360 
User U3 = 59 
U154 
User U1 = 53 
U254 
User U2 = 53 
U359 
User U3 = 58 
U153 
User U1 = 52 
U253 
User U2 = 52 
U358 
User U3 = 57 
// and so one 
+0

オブジェクトのロックは完全に機能しました!ドキュメントを掘り下げ、スレッディングについて学ぶ必要があります。あなたの答えをどうもありがとう、そして貢献した他の人にも感謝します! –

関連する問題