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#编写计算机选课程序

    在这篇文章中将介绍如何开发一个简单的计算机选课程序,文中主要使用了C#语言和Windows Forms来构建这个应用程序,感兴趣的小伙伴可以了解下
    2024-10-10
  • C#自定义事件及用法实例

    C#自定义事件及用法实例

    这篇文章主要介绍了C#自定义事件及用法,实例分析了C#中自定义事件的定义与使用技巧,需要的朋友可以参考下
    2015-05-05
  • C#数字图像处理之图像二值化(彩色变黑白)的方法

    C#数字图像处理之图像二值化(彩色变黑白)的方法

    这篇文章主要介绍了C#数字图像处理之图像二值化(彩色变黑白)的方法,可实现图像从彩色转变为黑白的效果,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • C#调用Python的URL接口的示例

    C#调用Python的URL接口的示例

    这篇文章主要介绍了C#调用Python的URL接口的示例,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下
    2020-10-10
  • C#中IDispose接口的实现及为何这么实现详解

    C#中IDispose接口的实现及为何这么实现详解

    这篇文章主要给大家介绍了关于C#中IDispose接口的实现及为何这么实现的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-05-05
  • c#使用IMap收取163邮件的方法示例

    c#使用IMap收取163邮件的方法示例

    大家都知道,设置IMAP服务后,不论是在客户端、手机、iPad还是网页中,发送邮件、阅读邮件后在各处均可以同步显示。下面这篇文章主要介绍了c#使用IMap收取163邮件的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
    2018-02-02
  • 详解WMI RPC 服务器不可用的解决方案

    详解WMI RPC 服务器不可用的解决方案

    这篇文章主要介绍了详解WMI RPC 服务器不可用的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01
  • WPF实现抽屉菜单效果的示例代码

    WPF实现抽屉菜单效果的示例代码

    这篇文章主要介绍了如何利用WPF实现抽屉菜单效果,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下
    2022-08-08
  • C# 建造者模式(Builder Pattern)详细讲解

    C# 建造者模式(Builder Pattern)详细讲解

    建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示,它适用于构建过程复杂且涉及多个步骤的场景,本文介绍C# 建造者模式(Builder Pattern)详细讲解,感兴趣的朋友一起看看吧
    2025-03-03
  • C#中调整图像大小的步骤详解

    C#中调整图像大小的步骤详解

    这篇文章主要介绍了C#中调整图像大小的步骤详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-05-05

最新评论