【问题标题】:Static dictionary contents not changing静态字典内容不变
【发布时间】:2012-11-13 10:30:50
【问题描述】:

我有一个问题,我希望很容易解决。在过去的几天里,我一直在寻找答案,但还没有运气。我想要做的是有一个静态字典来表示连接的客户端,最终目标是发送所有连接的客户端数据,例如其他玩家位置。无论如何,到目前为止我所做的是当客户端首次连接时,我将它们添加到静态字典中,如下所示:

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 循环从不迭代,因为字典中似乎没有客户端。任何帮助将不胜感激,这个问题一直让我发疯!提前致谢。

-贾里德

【问题讨论】:

  • 我看到的第一件事是完全缺乏同步......需要一些lock或类似的东西。添加后的计数是多少?在 foreach 之前的 Count 是什么?此外,您的循环很有可能永远不会看到对 isRunning 的更新(当然不能保证)。
  • 我对线程的经验并不丰富,但我也认为需要一些锁。我想我对锁的工作原理有了基本的了解。当我将客户端添加到字典时,我尝试添加一个锁。我还尝试将 foreach 循环放在有助于并发访问的锁中。我不确定这是否是正确的方法。至于计数,在更新部分的 foreach 循环之前计数为 0,这是我在尝试 foreach 之前所做的,只是为了查看计数是否在增加。
  • 添加后的计数为 1,但我没有添加该代码,因为下面的 foreach 语句表明我确实只是添加了一个值。至于循环,我确信循环正在运行,因为我之前在那里有一个调试语句,它每 100 毫秒触发一次。
  • 1.我看不到 isRunning 在哪里设置回 false。 2. 您肯定需要锁或切换到并发字典 3. 我注意到在第一个代码块中您列出了完整的命名空间,但在 foreach 循环中没有 - 您是否偶然指向了不同的实例?
  • 重点是 isRunning 在任何时候都没有设置为 false,至少在我希望应用程序运行时,因为这将更新玩家的位置并将该信息发送到所有 RegionClients。 Dictionary RegionClients 是静态的,因此没有实例。我应该更具体地说,完整的命名空间在第一个,因为它在不同的文件中。第二个代码块在 RegionServer 文件中,因此没有命名空间。我认为逻辑还可以,所以我确定它必须与同步有关。不幸的是,我还没有弄清楚这一点。

标签: c# dictionary thread-safety threadpool


【解决方案1】:

事实证明这很简单。我有一个集群服务器正在运行,我试图从不同的进程中引用这本字典......呃。感谢您的想法,事实证明这比尝试线程安全更简单。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-07
    • 2015-10-04
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多