服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - C#中Dictionary与ConcurrentDictionary解锁多线程操作安全之道

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

2024-04-03 14:32架构师老卢 C#

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

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

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

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

1. 使用Dictionary进行非线程安全操作

首先,我们来看一个使用普通的Dictionary的例子。在这个例子中,我们创建一个Dictionary对象,然后通过多个线程同时进行读取和写入操作,以演示潜在的线程安全问题。

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        // 创建一个非线程安全的 Dictionary
        Dictionary<int, string> regularDictionary = new Dictionary<int, string>();

        // 启动多个线程对字典进行读取和写入操作
        List<Task> tasks = new List<Task>();

        for (int i = 0; i < 10; i++)
        {
            int key = i;

            tasks.Add(Task.Run(() =>
            {
                // 读取和写入操作
                RegularDictionaryExample(regularDictionary, key);
            }));
        }

        // 等待所有任务完成
        Task.WaitAll(tasks.ToArray());

        Console.WriteLine("Regular Dictionary:");
        PrintDictionary(regularDictionary);

        Console.ReadLine();
    }

    // 非线程安全的字典操作示例
    static void RegularDictionaryExample(Dictionary<int, string> dictionary, int key)
    {
        if (dictionary.ContainsKey(key))
        {
            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} already exists. Value: {dictionary[key]}");
        }
        else
        {
            dictionary[key] = $"Value from Thread {Thread.CurrentThread.ManagedThreadId}";
            Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} added.");
        }
    }

    // 打印字典内容
    static void PrintDictionary<T, U>(Dictionary<T, U> dictionary)
    {
        foreach (var kvp in dictionary)
        {
            Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
        }
    }
}

2. 使用ConcurrentDictionary进行线程安全操作

接下来,我们使用ConcurrentDictionary来解决线程安全问题。ConcurrentDictionary提供了内置的线程安全机制,避免了多线程同时访问时的问题。

using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        // 创建一个线程安全的 ConcurrentDictionary
        ConcurrentDictionary<int, string> concurrentDictionary = new ConcurrentDictionary<int, string>();

        // 启动多个线程对字典进行读取和写入操作
        List<Task> tasks = new List<Task>();

        for (int i = 0; i < 10; i++)
        {
            int key = i;

            tasks.Add(Task.Run(() =>
            {
                // 读取和写入操作
                ConcurrentDictionaryExample(concurrentDictionary, key);
            }));
        }

        // 等待所有任务完成
        Task.WaitAll(tasks.ToArray());

        Console.WriteLine("\nConcurrent Dictionary:");
        PrintDictionary(concurrentDictionary);

        Console.ReadLine();
    }

    // 线程安全的字典操作示例
    static void ConcurrentDictionaryExample(ConcurrentDictionary<int, string> dictionary, int key)
    {
        string value = dictionary.GetOrAdd(key, k => $"Value from Thread {Thread.CurrentThread.ManagedThreadId}");
        Console.WriteLine($"Thread {Thread.CurrentThread.ManagedThreadId}: Key {key} {((value == null) ? "added" : "already exists")}. Value: {value}");
    }

    // 打印字典内容
    static void PrintDictionary<T, U>(ConcurrentDictionary<T, U> dictionary)
    {
        foreach (var kvp in dictionary)
        {
            Console.WriteLine($"Key: {kvp.Key}, Value: {kvp.Value}");
        }
    }
}
  • Dictionary问题: 普通的Dictionary在多线程环境中可能导致数据不一致或异常,因为它不提供线程安全性。
  • ConcurrentDictionary解决方案: ConcurrentDictionary是专为多线程设计的,通过提供内置的线程安全机制,确保在多线程环境中对字典进行安全的读取和写入操作。
  • GetOrAdd方法: ConcurrentDictionary的GetOrAdd方法是线程安全的读取和写入的原子操作,可以安全地在多线程环境中使用。

通过选择适当的字典类型,可以确保在多线程应用程序中有效地管理数据,避免潜在的线程安全问题。

原文地址:https://www.toutiao.com/article/7304992680860336676/

延伸 · 阅读

精彩推荐
  • C#C#实现计算器功能

    C#实现计算器功能

    这篇文章主要为大家详细介绍了C#实现计算器功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    剧里局外11572022-12-22
  • C#c# 使用谷歌身份验证器GoogleAuthenticator的示例

    c# 使用谷歌身份验证器GoogleAuthenticator的示例

    这篇文章主要介绍了c# 使用谷歌身份验证器GoogleAuthenticator的示例,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...

    心如大海6392022-10-31
  • C#C# this关键字的四种用法

    C# this关键字的四种用法

    这篇文章主要为大家详细介绍了C# this关键字的四种用法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    天碼亦行空10392021-12-13
  • C#Unity扩展Hierachry的右键菜单

    Unity扩展Hierachry的右键菜单

    这篇文章主要为大家详细介绍了Unity扩展Hierachry的右键菜单,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    yangrc12344252022-03-10
  • C#C# 使用AE获取feature的属性及字段操作

    C# 使用AE获取feature的属性及字段操作

    这篇文章主要介绍了C# 使用AE获取feature的属性及字段操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    南方北先生9862022-10-27
  • C#C# 通过 oledb 操作Excel实例代码

    C# 通过 oledb 操作Excel实例代码

    本篇文章主要介绍了C# 通过 oledb 操作Excel实例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...

    李子康3782022-01-06
  • C#c# base64转字符串实例

    c# base64转字符串实例

    这篇文章主要介绍了c# base64转字符串实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    萌橙9142022-10-20
  • C#C#根据IP地址查询所属地区实例详解

    C#根据IP地址查询所属地区实例详解

    这篇文章主要介绍了C#根据IP地址查询所属地区实例详解,调用的接口是免费的接口,有需要的同学可以研究下...

    祝君圆梦4632022-11-04