【问题标题】:Static collection dictionary in WCFWCF 中的静态集合字典
【发布时间】:2012-09-17 12:10:43
【问题描述】:

我正在编写跟踪类来查找模块/方法的执行时间。我有这样的课

public class Trace
    {
        static Dictionary<string, Stopwatch> watches = null;

        static Trace()
        {
            Dictionary<string, Stopwatch> watches = new Dictionary<string, Stopwatch>();
        }

        public static void Start(string key, string losgMessage)
        {
            try
            {
                if (!watches.Keys.Contains(key))
                {
                    Stopwatch watch = new Stopwatch();
                    watch.Start();
                    watches.Add(key, watch);
                }
            }
            catch
            {
            }
        }

        public static void Stop(string key, Object logMessage, string sessionId)
        {
            try
            {

                if (!watches.Keys.Contains(key))
                {
                    Stopwatch watch = watches[key];
                    watch.Stop();
                    //log goes here
                }
            }
            catch
            {
            }
        }
    }

由于 wcf 是多线程环境并且“watches”静态变量范围是应用程序级别,如果有人(来自不同客户端的新 rqst)尝试使用相同的键执行相同的方法,我不会考虑并跟踪它。那么在这种情况下,最好的选择是什么。任何建议都会有所帮助。

edit:我当前正在附加 sessionId 和密钥。如果没有会话 ID,我无法解决此问题

【问题讨论】:

  • 从外观上看你也有一个sessionId,也许将它附加到功能键以使其唯一不是更可靠吗?
  • 另外,您需要在 Start 和 Stop 方法中使用locks,因为它们正在读/写字典,而其他线程可能同时在处理它。
  • 我相信您不打算将它与任何递归方法一起使用。
  • "是的,我目前正在这样做" - 如果是这种情况,那么重复条目应该没有问题 - 假设所有请求都有唯一的会话 ID。跨度>
  • 是的,我没有在记录中这样做。方法

标签: c# multithreading wcf static


【解决方案1】:

如果没有会话 ID,我无法解决此问题

根据提供的信息,我会说不。如果您有并发请求执行相同的函数调用,那么您将获得重复的条目。避免这种情况的唯一方法是确保 all 键是唯一的。我实际上认为无论如何都需要使用会话 ID,否则如何将函数映射到请求?

另外,Dictionary 不是线程安全的(至少对于写入而言),我建议使用 ConcurrentDictionary

【讨论】:

  • 如果我使用ConcurrentDictionary,在普通字典中添加/检索/删除之前不需要使用锁吗?
  • "在添加/检索/删除之前我不需要使用锁" - 不,ConcurrentDictionary 是线程安全的,因此可以直接从多个线程访问,所有的锁定都是在内部处理的。
  • stackoverflow.com/questions/1949131/… -> Mark Byers 声称它仍然需要锁定。是不是这样
  • Mark Byers 关于比赛条件的观点,例如您在集合上调用Contains 以检查重复键,然后尝试添加该键(如果它不存在)。但是,并发线程可能在调用之间添加了相同的键。在您的场景中,您没有任何理由这样做,因为您的所有密钥都是唯一的。此外,ConcurrentDictionary 有避免此类问题的方法 - GetOrAdd
  • 非常感谢。让我解除锁定并使用 ConcurrentDictionary
猜你喜欢
  • 1970-01-01
  • 2017-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-30
  • 1970-01-01
相关资源
最近更新 更多