翼度科技»论坛 编程开发 .net 查看内容

C#中Dictionary与ConcurrentDictionary解锁多线程操作安全之道

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
 
使用C#中的Dictionary与ConcurrentDictionary进行多线程操作

在C#中,Dictionary是一个常见的字典类型,但它不是线程安全的。为了在多线程环境中确保安全的操作,我们可以使用ConcurrentDictionary,这是一个专门设计用于多线程场景的线程安全字典。
1. 使用Dictionary进行非线程安全操作

首先,我们来看一个使用普通的Dictionary的例子。在这个例子中,我们创建一个Dictionary对象,然后通过多个线程同时进行读取和写入操作,以演示潜在的线程安全问题。
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. class Program
  6. {
  7.     static void Main()
  8.     {
  9.         // 创建一个非线程安全的 Dictionary
  10.         Dictionary<int, string> regularDictionary = new Dictionary<int, string>();
  11.         // 启动多个线程对字典进行读取和写入操作
  12.         List<Task> tasks = new List<Task>();
  13.         for (int i = 0; i < 10; i++)
  14.         {
  15.             int key = i;
  16.             tasks.Add(Task.Run(() =>
  17.             {
  18.                 // 读取和写入操作
  19.                 RegularDictionaryExample(regularDictionary, key);
  20.             }));
  21.         }
  22.         // 等待所有任务完成
  23.         Task.WaitAll(tasks.ToArray());
  24.         Console.WriteLine("Regular Dictionary:");
  25.         PrintDictionary(regularDictionary);
  26.         Console.ReadLine();
  27.     }
  28.     // 非线程安全的字典操作示例
  29.     static void RegularDictionaryExample(Dictionary<int, string> dictionary, int key)
  30.     {
  31.         if (dictionary.ContainsKey(key))
  32.         {
  33.             Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} already exists. Value: {dictionary[key]}");
  34.         }
  35.         else
  36.         {
  37.             dictionary[key] = $"Value from Thread {Thread.CurrentThread.ManagedThreadId}";
  38.             Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} added.");
  39.         }
  40.     }
  41.     // 打印字典内容
  42.     static void PrintDictionary<T, U>(Dictionary<T, U> dictionary)
  43.     {
  44.         foreach (var kvp in dictionary)
  45.         {
  46.             Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
  47.         }
  48.     }
  49. }
复制代码
2. 使用ConcurrentDictionary进行线程安全操作

接下来,我们使用ConcurrentDictionary来解决线程安全问题。ConcurrentDictionary提供了内置的线程安全机制,避免了多线程同时访问时的问题。
  1. using System;
  2. using System.Collections.Concurrent;
  3. using System.Threading;
  4. using System.Threading.Tasks;
  5. class Program
  6. {
  7.     static void Main()
  8.     {
  9.         // 创建一个线程安全的 ConcurrentDictionary
  10.         ConcurrentDictionary<int, string> concurrentDictionary = new ConcurrentDictionary<int, string>();
  11.         // 启动多个线程对字典进行读取和写入操作
  12.         List<Task> tasks = new List<Task>();
  13.         for (int i = 0; i < 10; i++)
  14.         {
  15.             int key = i;
  16.             tasks.Add(Task.Run(() =>
  17.             {
  18.                 // 读取和写入操作
  19.                 ConcurrentDictionaryExample(concurrentDictionary, key);
  20.             }));
  21.         }
  22.         // 等待所有任务完成
  23.         Task.WaitAll(tasks.ToArray());
  24.         Console.WriteLine("\nConcurrent Dictionary:");
  25.         PrintDictionary(concurrentDictionary);
  26.         Console.ReadLine();
  27.     }
  28.     // 线程安全的字典操作示例
  29.     static void ConcurrentDictionaryExample(ConcurrentDictionary<int, string> dictionary, int key)
  30.     {
  31.         string value = dictionary.GetOrAdd(key, k => $"Value from Thread {Thread.CurrentThread.ManagedThreadId}");
  32.         Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} {((value == null) ? "added" : "already exists")}. Value: {value}");
  33.     }
  34.     // 打印字典内容
  35.     static void PrintDictionary<T, U>(ConcurrentDictionary<T, U> dictionary)
  36.     {
  37.         foreach (var kvp in dictionary)
  38.         {
  39.             Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
  40.         }
  41.     }
  42. }
复制代码

  • Dictionary问题: 普通的Dictionary在多线程环境中可能导致数据不一致或异常,因为它不提供线程安全性。
  • ConcurrentDictionary解决方案: ConcurrentDictionary是专为多线程设计的,通过提供内置的线程安全机制,确保在多线程环境中对字典进行安全的读取和写入操作。
  • GetOrAdd方法: ConcurrentDictionary的GetOrAdd方法是线程安全的读取和写入的原子操作,可以安全地在多线程环境中使用。
通过选择适当的字典类型,可以确保在多线程应用程序中有效地管理数据,避免潜在的线程安全问题。



来源:https://www.cnblogs.com/hanbing81868164/p/17979223
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具