在ConcurrentDictionary中,读取操作是否读取最新的更新值?

时间:2016-02-21 22:43:14

标签: c# concurrentdictionary

我在代码中使用ConcurrentDictionaryongoingConnectionDic):

  1. 我检查字典中是否存在串口号。
  2. 如果不存在,我将其添加到字典中。
  3. 我与串口进行通信。
  4. 我从ongoingConnectionDic
  5. 中删除了该元素
  6. 如果存在,我将线程等待。
  7. 我的问题是,我可以确保在执行读取操作时,没有其他线程同时写入/更新值吗?那么,我是否正在阅读字典的最新价值?

    如果没有,我如何实现我的目标?

    示例程序:

        class Program
    {
        // Dictionary in question
        private static ConcurrentDictionary<string, string> ongoingPrinterJobs = 
            new ConcurrentDictionary<string, string>();
    
        private static void sendPrint(string printerName)
        {
            if (ongoingPrinterJobs.ContainsKey(printerName))
            {
                // Add to pending list and run a thread to finish pending jobs by calling print();
    
    
            }
            else
            {
                ongoingPrinterJobs.TryAdd(printerName, ""); // -- Add it to the dictionary so that no other thread can
                                                            // use the printer
    
                ThreadPool.QueueUserWorkItem(new WaitCallback(print), printerName);
            }
    
        }
    
        private static void print(object stateInfo)
        {
            string printerName = (stateInfo as string);
            string dummy;
            // do printing work
    
            // Remove from dictionary
            ongoingPrinterJobs.TryRemove(printerName, out dummy);
        }
    
    
        static void Main(string[] args)
        {
    
            // Run threads here in random to print something on different printers
            // Sample run with 10 printers
            Random r = new Random();
            for ( int i = 0 ; i < 10 ; i++ )
            {
                sendPrint(r.Next(0, 10).ToString());
            }
    
    
    
        }
    

1 个答案:

答案 0 :(得分:1)

并发集合采用&#34;快照&#34;在列举时的集合。这是为了防止枚举器在另一个线程出现并写入集合时变为无效。

ContainsKey之类的方法可以枚举字典中的项目(您必须查看实现),在这种情况下,您可能正在阅读陈旧数据。

允许您执行的所有并发集合确保您可以枚举集合,即使在您枚举时另一个线程写入它也是如此。标准集合的情况并非如此。

话虽如此,正如其他人在评论中提到的那样,其他线程安全问题仍必须考虑(例如竞争条件)。

在您尝试读取值之后但在写入ia值之前,阻止某人将值插入集合的唯一方法是在读取值之前lock集合,到确保在整个事务中对集合的同步访问(即读取和后续写入值)。