当前位置: 首页 > news >正文

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

注意事项

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

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

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

相关文章:

  • 使用 SQL CTE(公共表表达式)优化数据查询的实践
  • 文件的打开与关闭
  • 【MATLAB例程】三维环境下,动态轨迹的AOA定位与UKF滤波,模拟IMU/AOA的数据融合(AOA的测角基站数量可自适应,目标运动轨迹可自行修改)
  • 蓝桥杯day1-时间问题
  • 设计模式(创建型)- 原型模式
  • Transformer | 一文了解:缩放、批量、多头、掩码、交叉注意力机制(Attention)
  • 计算机视觉算法实战——手术导航:技术、应用与未来
  • PySimpleGUI安装老版本,给软件链接,免费用,教程
  • NO.58十六届蓝桥杯备战|基础算法-枚举|普通枚举|二进制枚举|铺地毯|回文日期|扫雷|子集|费解的开关|Even Parity(C++)
  • 二分查找模板--从题目中讲解三大二分模板
  • 谈谈对spring IOC的理解,原理和实现
  • 【大模型】数字人 Sonic 的环境配置和使用
  • HDR(HDR10/ HLG),SDR
  • Appium 入门操作指南
  • 无耳 Solon v3.1.1 发布(兼容 Java 24)
  • 3-2RYU控制器应用程序开发(一)
  • 如何从零构建Spring Boot Starter并实现整合
  • 【c++深入系列】:类与对象详解(上)
  • 解锁Spring Boot异步编程:让你的应用“飞“起来!
  • 【MLP-BEV(10)】BEVPooling V1和BEVPooling V2的view_transformer,进行鱼眼图片实践
  • 承接各类网站建设/网络推广培训课程内容
  • 国内 wordpress 大战/南宁seo内部优化
  • 优酷wordpress建站教程/百度怎么优化网站排名
  • 百度注册域名免费建站/长尾关键词挖掘工具爱网站
  • 学院评估 网站建设整改/seo公司怎么样
  • 郑州的做网站公司哪家好/云seo关键词排名优化软件