2012-11-25 37 views
0

我有一個問題,我希望很容易解決。我已經搜索了過去幾天的答案,但沒有運氣。我想要做的是有一個靜態字典表示連接的客戶端,最終目標是發送所有連接的客戶端數據,如其他玩家位置。不管怎麼說,我目前所做的就是當客戶第一次連接,我將它們添加到靜態辭典像這樣:靜態字典內容不變

RegionServer.RegionClients.Add(UserId, this); 
Log.DebugFormat("Added peer to region list"); 

foreach (var client in RegionServer.RegionClients) 
{ 
    Log.DebugFormat("Client id in list : {0}", client.Key); 
} 

我在調試語句加入,以確保客戶端真的被添加到這是它的名單。

然後在我的主文件我有:

public override void InitBackgroundThreads() 
    { 
     ThreadPool.QueueUserWorkItem(SendUpdatesToAll); 
    } 

public void SendUpdatesToAll(object threadContext) 
    { 
     Stopwatch timer = new Stopwatch(); 
     timer.Start(); 
     isRunning = true; 

     while (isRunning) 
     { 
      if (timer.Elapsed < TimeSpan.FromMilliseconds(100)) 
       continue; 

      Update(timer.Elapsed); 
      timer.Restart(); 
     } 
    } 

public void Update(TimeSpan elapsed) 
    { 

     foreach (KeyValuePair<Guid, Unity3dPeer> peer in RegionClients) 
       { 
        Log.DebugFormat("Inside the foreach statement"); 
       } 

在我的調試日誌,我可以看到,環確實循環,但永遠不會更新RegionClients字典中的值。 foreach循環從不迭代,因爲在字典中似乎沒有客戶端。任何幫助將不勝感激,這個問題一直讓我瘋狂!提前致謝。

-Jarryd

+1

我看到的第一件事是完全缺乏同步......需要一些「鎖定」或類似的東西。添加後的計數是多少?伯爵之前的伯爵是什麼?另外,你的循環可能永遠不會看到更新isRunning(它肯定不能保證)。 –

+0

我對線程並沒有很好的經驗,但我也認爲需要一些鎖。我想我對鎖的工作原理有了基本的瞭解。我試過的是當我將客戶端添加到字典時添加一個鎖。我也嘗試把foreach循環放在一個鎖中,這會有助於併發訪問。我不確定這是否正確。至於計數,在更新部分的foreach循環之前count是0,這正是我在嘗試使用foreach之前就已經到位的地方,只是爲了確定count是否增加。 – Jarryd

+0

添加後計數爲1,但我沒有添加該代碼,但正如下面的foreach語句顯示我確實只是添加了一個值。至於循環,我確定循環正在運行,因爲我之前在那裏有一個調試語句,每隔100ms觸發一次。 – Jarryd

回答

0

事實證明這很簡單。我有一個集羣服務器,我試圖從不同的進程中引用這個字典......杜。感謝這些想法,結果比嘗試線程安全更簡單。