C#实现读写分离的五种方法小结

 更新时间:2025年03月28日 11:40:37   作者:就是有点傻  
在C#中实现分离功能通常指的是将不同的逻辑或责任分配到不同的类或组件中,以增强代码的可读性、可维护性和可扩展性,这通常涉及到设计模式、依赖注入和接口的使用,下面是一些在C#中实现分离功能的基本方法,需要的朋友可以参考下

1. 使用 ReaderWriterLockSlim

.NET 提供的高性能读写锁,支持以下模式:

  • 读模式(Read Lock):允许多个线程同时读取。

  • 写模式(Write Lock):独占锁,其他所有读写操作都会被阻塞。

using System.Threading;
 
public class ReadWriteExample
{
    private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
    private int _sharedData = 0;
 
    // 读操作
    public int ReadData()
    {
        _lock.EnterReadLock();
        try
        {
            return _sharedData;
        }
        finally
        {
            _lock.ExitReadLock();
        }
    }
 
    // 写操作
    public void WriteData(int value)
    {
        _lock.EnterWriteLock();
        try
        {
            _sharedData = value;
        }
        finally
        {
            _lock.ExitWriteLock();
        }
    }
}

优点

  • 细粒度控制读写操作。

  • 支持递归锁和超时机制。

缺点

  • 需要手动管理锁的获取和释放。

2. 使用 Concurrent 并发集合

.NET 的 System.Collections.Concurrent 命名空间提供了线程安全的集合类,内部已实现读写分离逻辑:

  • ConcurrentDictionary<TKey, TValue>

  • ConcurrentQueue<T>

  • ConcurrentBag<T>

using System.Collections.Concurrent;
 
public class ConcurrentExample
{
    private readonly ConcurrentDictionary<string, int> _data = new();
 
    // 读操作(无锁)
    public int GetValue(string key)
    {
        return _data.TryGetValue(key, out int value) ? value : -1;
    }
 
    // 写操作(内部使用细粒度锁)
    public void UpdateValue(string key, int value)
    {
        _data.AddOrUpdate(key, value, (k, oldValue) => value);
    }
}

优点

  • 开箱即用,无需手动管理锁。

  • 高性能,适合高频读写场景。

缺点

  • 灵活性较低,仅适用于预定义的集合类型。

3. 基于 volatile 和内存屏障(Memory Barrier)

适用于简单变量的读写分离,通过 volatile 关键字确保内存可见性:

public class VolatileExample
{
    private volatile bool _flag = false;
    private int _data = 0;
 
    // 读操作(无锁)
    public int ReadData()
    {
        if (_flag)
            return _data;
        return -1;
    }
 
    // 写操作(需要同步)
    public void WriteData(int value)
    {
        Interlocked.Exchange(ref _data, value); // 原子写入
        Volatile.Write(ref _flag, true);        // 确保写入对其他线程可见
    }
}

优点

  • 轻量级,适合简单场景。

  • 无锁读操作。

缺点

  • 仅适用于简单类型(如 intbool)。

  • 需要手动处理内存可见性。

4. 数据库读写分离

在数据库层面实现读写分离(如主从架构),C# 代码通过不同连接字符串路由请求:

public class DatabaseRouter
{
    private static readonly string ReadConnectionString = "Server=ReadServer;...";
    private static readonly string WriteConnectionString = "Server=WriteServer;...";
 
    public IDbConnection GetReadConnection() => 
        new SqlConnection(ReadConnectionString);
 
    public IDbConnection GetWriteConnection() => 
        new SqlConnection(WriteConnectionString);
}
 
// 使用示例
using (var readConn = DatabaseRouter.GetReadConnection())
{
    // 执行查询操作
}
 
using (var writeConn = DatabaseRouter.GetWriteConnection())
{
    // 执行更新操作
}

优点

  • 直接利用数据库主从复制特性。

  • 减轻主库压力。

缺点

  • 需要数据库支持主从同步。

  • 可能存在数据同步延迟。

5. 基于不可变数据(Immutable Data)

通过每次修改生成新对象实现无锁读取(如使用 ImmutableList<T> 或自定义不可变类型):

using System.Collections.Immutable;
 
public class ImmutableExample
{
    private ImmutableList<int> _data = ImmutableList<int>.Empty;
 
    // 读操作(无锁)
    public int GetItem(int index)
    {
        return _data[index];
    }
 
    // 写操作(原子替换)
    public void AddItem(int item)
    {
        ImmutableInterlocked.Update(ref _data, list => list.Add(item));
    }
}

优点

  • 完全无锁读取。

  • 天然线程安全。

缺点

  • 频繁修改可能产生内存压力。

选择策略

场景推荐方案
细粒度代码级读写控制ReaderWriterLockSlim
高频并发集合操作ConcurrentDictionary 等并发集合
简单变量的读写volatile + Interlocked
数据库访问分离主从架构 + 连接路由
高频读、低频写不可变数据(如 ImmutableList

注意事项

  • 避免死锁确保锁的获取和释放成对出现(用 try-finally 块)。

  • 性能权衡:读写锁适合读多写少场景,写频繁时可能不如普通锁高效。

  • 数据一致性:数据库读写分离时需处理主从同步延迟问题。

到此这篇关于C#实现读写分离的五种方法小结的文章就介绍到这了,更多相关C#读写分离内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 采用C#代码动态设置文件权限

    采用C#代码动态设置文件权限

    在开发中,我们经常会使用IO操作,例如创建,删除文件等操作。在项目中这样的需求也较多,我们也会经常对这些操作进行编码,但是对文件的权限进行设置,这样的操作可能会手动操作,本文介绍一种采用代码动态对文件设置权限的操作。
    2016-12-12
  • 使用MSScriptControl 在 C# 中读取json数据的方法

    使用MSScriptControl 在 C# 中读取json数据的方法

    下面小编就为大家带来一篇使用MSScriptControl 在 C# 中读取json数据的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • ActiveMQ在C#中的应用示例分析

    ActiveMQ在C#中的应用示例分析

    这篇文章主要介绍了ActiveMQ在C#中的应用,简单介绍了ActiveMQ的功能、下载及在C#中的具体使用方法,需要的朋友可以参考下
    2016-07-07
  • C#编程之AOP编程思想

    C#编程之AOP编程思想

    这篇文章介绍了C#编程之AOP编程思想,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03
  • C# 正则表达式常用的符号和模式解析(最新推荐)

    C# 正则表达式常用的符号和模式解析(最新推荐)

    这篇文章主要介绍了C# 正则表达式常用的符号和模式解析,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • C# Environment.CurrentDirectory 静态属性的实现

    C# Environment.CurrentDirectory 静态属性的实现

    本文主要介绍了C# Environment.CurrentDirectory 静态属性的实现,它返回当前应用程序的工作目录路径,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • C#二叉搜索树算法实现步骤和实例代码

    C#二叉搜索树算法实现步骤和实例代码

    二叉搜索树(Binary Search Tree,简称BST)是一种节点有序排列的二叉树数据结构,这篇文章主要介绍了C#二叉搜索树算法实现步骤和实例代码,需要的朋友可以参考下
    2024-08-08
  • C#正则表达式与HashTable详解

    C#正则表达式与HashTable详解

    这篇文章主要介绍了C#正则表达式与HashTable详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-07-07
  • C#绘制飞行棋地图小程序

    C#绘制飞行棋地图小程序

    这篇文章主要介绍了C#绘制飞行棋地图小程序的相关资料,非常不错,具有参考借鉴价值,对c飞行棋地图相关知识感兴趣的朋友一起看看吧
    2016-09-09
  • C#基础知识之字符串和正则表达式

    C#基础知识之字符串和正则表达式

    目前为止许多编程语言和工具都包含对正则表达式的支持,C#也不例外,下面这篇文章主要给大家介绍了关于C#基础知识之字符串和正则表达式的相关资料,需要的朋友可以参考下
    2022-10-10

最新评论