转自:阿里的 通义灵码
接上篇:https://www.cnblogs.com/z5337/p/18181574
在 C# 中防止接口的并发访问(即确保同一时间内只有一个线程能够访问某个资源或方法),可以通过多种方式实现。这里列出一些常见的方法:
1. 使用 lock
语句
lock
是一种常用的同步原语,用于保护对共享资源的访问。它会获取一个对象的互斥锁,在释放锁之前阻止其他线程获取同一个锁。
private readonly object _lockObject = new object(); public void SafeMethod() { lock (_lockObject) { // 这里是临界区,一次只有一个线程能进入 // 执行你的业务逻辑 } }
2. 使用 Monitor
类
Monitor
类提供了比 lock
更加灵活的控制,包括等待条件、超时等。
private readonly object _monitorLock = new object(); public void SafeMethod() { Monitor.Enter(_monitorLock); try { // 执行业务逻辑 } finally { Monitor.Exit(_monitorLock); } }
3. 使用 Semaphore
或 SemaphoreSlim
信号量可以用来限制同时访问某个资源的线程数量。
private readonly SemaphoreSlim _semaphore = new SemaphoreSlim(1, 1); public async Task SafeAsyncMethod() { await _semaphore.WaitAsync(); try { // 执行业务逻辑 } finally { _semaphore.Release(); } }
4. 使用 async/await
和线程安全集合
如果你的方法是异步的,并且需要访问集合,可以考虑使用线程安全的集合,如 ConcurrentBag
, ConcurrentQueue
, ConcurrentStack
等。
private readonly ConcurrentBag<int> _threadSafeCollection = new ConcurrentBag<int>(); public async Task SafeAsyncMethod() { // 添加元素 _threadSafeCollection.Add(1); // 获取元素 int value; _threadSafeCollection.TryTake(out value); }
5. 使用 ReaderWriterLockSlim
当你有多个读取者但很少有写入者时,ReaderWriterLockSlim
允许多个读取者同时访问资源,但不允许写入者和其他读取者同时访问。
private readonly ReaderWriterLockSlim _readerWriterLock = new ReaderWriterLockSlim(); public void SafeReadMethod() { _readerWriterLock.EnterReadLock(); try { // 读取操作 } finally { _readerWriterLock.ExitReadLock(); } } public void SafeWriteMethod() { _readerWriterLock.EnterWriteLock(); try { // 写入操作 } finally { _readerWriterLock.ExitWriteLock(); } }
选择哪种方法取决于你的具体需求和场景。例如,如果你的应用程序主要是异步的,那么使用 SemaphoreSlim
或 async/await
结合线程安全集合可能是更好的选择。如果你的应用程序是同步的,那么 lock
或 Monitor
可能就足够了。而对于读多写少的场景,ReaderWriterLockSlim
则是一个不错的选择。