当前位置:首页 > C# > 正文

C#读写锁详解(ReaderWriterLockSlim多线程同步实战指南)

在C#多线程编程中,如何高效地处理多个线程对共享资源的并发访问是一个常见且关键的问题。当多个线程只需要读取数据而很少修改时,使用传统的互斥锁(如lock)会导致不必要的性能瓶颈——因为即使只是读操作,也会被串行化执行。

这时,C#读写锁ReaderWriterLockSlim)就派上用场了!它允许多个读线程同时访问资源,但在写操作发生时会独占资源,从而在保证线程安全的同时显著提升并发性能。

C#读写锁详解(ReaderWriterLockSlim多线程同步实战指南) C#读写锁 ReaderWriterLockSlim教程 多线程同步 C#并发控制 第1张

什么是 ReaderWriterLockSlim?

ReaderWriterLockSlim 是 .NET Framework 3.5 引入的一个轻量级、高性能的读写锁实现,用于替代旧版的 ReaderWriterLock。它支持三种模式:

  • 读模式(Read):允许多个线程同时进入,适用于只读操作。
  • 写模式(Write):仅允许一个线程进入,适用于修改操作。
  • 可升级读模式(Upgradeable Read):先以读模式进入,后续可升级为写模式(需谨慎使用,避免死锁)。

基本使用方法

下面是一个完整的 C# 读写锁使用示例,演示如何安全地对一个共享字典进行读写操作:

using System;using System.Collections.Generic;using System.Threading;public class SafeCache{    private readonly ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();    private readonly Dictionary<string, string> _cache = new Dictionary<string, string>();    // 读取数据    public string GetValue(string key)    {        _lock.EnterReadLock();        try        {            return _cache.TryGetValue(key, out var value) ? value : null;        }        finally        {            _lock.ExitReadLock();        }    }    // 写入数据    public void SetValue(string key, string value)    {        _lock.EnterWriteLock();        try        {            _cache[key] = value;        }        finally        {            _lock.ExitWriteLock();        }    }    // 安全释放资源    public void Dispose()    {        _lock?.Dispose();    }}

注意:必须try-finally 块中调用 ExitReadLock()ExitWriteLock(),确保即使发生异常也能正确释放锁,避免死锁。

可升级读模式(Upgradeable Read)

当你不确定是否需要写入,但希望先读取再决定是否更新时,可以使用可升级读模式:

public void AddIfNotExists(string key, string value){    _lock.EnterUpgradeableReadLock();    try    {        if (!_cache.ContainsKey(key))        {            _lock.EnterWriteLock();            try            {                _cache[key] = value;            }            finally            {                _lock.ExitWriteLock();            }        }    }    finally    {        _lock.ExitUpgradeableReadLock();    }}

⚠️ 警告:可升级读锁在同一时间只能有一个线程持有,否则可能导致死锁。因此应尽量减少其使用频率。

最佳实践与注意事项

  • 始终使用 try-finally 确保锁被释放。
  • 避免在持有读锁时执行耗时操作(如 I/O),以免阻塞写线程。
  • 不要在锁内调用外部代码(如事件回调),以防死锁。
  • 使用完毕后调用 Dispose() 释放内部资源。
  • 对于简单场景,可考虑使用 ConcurrentDictionary 等线程安全集合,避免手动加锁。

总结

ReaderWriterLockSlim 是 C# 并发控制 中非常实用的工具,特别适合“多读少写”的场景。通过合理使用读写锁,你可以在保证线程安全的同时最大化程序的并发性能。

掌握 C#读写锁ReaderWriterLockSlim教程多线程同步C#并发控制 这些核心概念,将帮助你在开发高性能多线程应用时游刃有余。

希望这篇教程能帮你轻松理解并应用 ReaderWriterLockSlim!