小疯 發表於 2026-1-9 10:04:19

C#多线程访问资源的实现示例

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li>1.1 锁机制</li><ul class="second_class_ul"><li>1.2 信号量机制</li><li>1.3 事件与信号</li><li>1.4 原子操作</li><li>1.5 线程安全集合</li><li>1.6 避免共享状态</li><li>1.7 异步与并行</li><li>1.8 选择策略</li></ul></ul></div><p>在 C# 中,多线程访问共享资源需要通过同步机制来保证线程安全。以下是常见的解决方案及其适用场景:</p>
<p class="maodian"></p><h2>1.1 锁机制</h2>
<ol><li><p><code>lock</code> 关键字</p>
<ul><li>基于 <code>Monitor</code> 类,确保代码块同一时间仅一个线程进入。</li><li>适用场景:简单临界区保护。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">private readonly object _lockObj = new object();
lock (_lockObj)
{
    // 访问共享资源
}
</pre></div></li><li><p><code>Monitor</code> 类</p>
<ul><li>提供更灵活的控制(如超时机制)。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">Monitor.Enter(_lockObj);
try { /* 操作资源 */ }
finally { Monitor.Exit(_lockObj); }
</pre></div></li><li><p><code>Mutex</code> (互斥锁)</p>
<ul><li>跨进程同步,适用于多进程共享资源。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">using var mutex = new Mutex(false, "GlobalMutexName");
mutex.WaitOne();
try { /* 操作资源 */ }
finally { mutex.ReleaseMutex(); }
</pre></div></li><li><p><code>SpinLock</code> (自旋锁)</p>
<ul><li>通过循环等待避免上下文切换,适用于极短临界区。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">SpinLock spinLock = new SpinLock();
bool lockTaken = false;
spinLock.Enter(ref lockTaken);
try { /* 操作资源 */ }
finally { if (lockTaken) spinLock.Exit(); }
</pre></div></li></ol>
<p class="maodian"></p><h3>1.2 信号量机制</h3>
<ol><li><p><code>Semaphore</code> / <code>SemaphoreSlim</code></p>
<ul><li>控制同时访问资源的线程数量。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">SemaphoreSlim semaphore = new SemaphoreSlim(3); // 允许3个线程进入
await semaphore.WaitAsync();
try { /* 操作资源 */ }
finally { semaphore.Release(); }
</pre></div></li><li><p><code>ReaderWriterLockSlim</code></p>
<ul><li>读写分离锁,允许多读单写。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">ReaderWriterLockSlim rwLock = new ReaderWriterLockSlim();
rwLock.EnterReadLock();// 读模式
try { /* 读取资源 */ }
finally { rwLock.ExitReadLock(); }

rwLock.EnterWriteLock(); // 写模式
try { /* 修改资源 */ }
finally { rwLock.ExitWriteLock(); }
</pre></div></li></ol>
<p class="maodian"></p><h3>1.3 事件与信号</h3>
<ol><li><p><code>ManualResetEvent</code> / <code>AutoResetEvent</code></p>
<ul><li>通过信号控制线程阻塞与唤醒。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne();    // 等待信号
mre.Set();      // 发送信号
</pre></div></li><li><p><code>Barrier</code> (屏障)</p>
<ul><li>同步多个线程到同一阶段。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">Barrier barrier = new Barrier(3); // 等待3个线程到达
barrier.SignalAndWait();          // 每个线程调用此方法
</pre></div></li><li><p><code>CountdownEvent</code></p>
<ul><li>等待指定数量的操作完成。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">CountdownEvent cde = new CountdownEvent(3);
cde.Signal();// 每个线程完成后调用
cde.Wait();    // 等待所有完成
</pre></div></li></ol>
<p class="maodian"></p><h3>1.4 原子操作</h3>
<ol><li><p><code>Interlocked</code> 类</p>
<ul><li>提供原子操作(如递增、比较交换)。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">int value = 0;
Interlocked.Increment(ref value); // 原子递增
</pre></div></li></ol>
<p class="maodian"></p><h3>1.5 线程安全集合</h3>
<ol><li><p><code>ConcurrentQueue</code> / <code>ConcurrentDictionary</code> 等</p>
<ul><li>内置线程安全的集合,避免手动同步。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">var queue = new ConcurrentQueue&lt;int&gt;();
queue.Enqueue(1);
if (queue.TryDequeue(out var item)) { /* 处理元素 */ }
</pre></div></li></ol>
<p class="maodian"></p><h3>1.6 避免共享状态</h3>
<ol><li><p>不可变对象</p>
<ul><li>使用 <code>readonly</code> 或不可变集合(如 <code>ImmutableList</code>),确保数据不可变。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">var list = ImmutableList.Create&lt;int&gt;();
list = list.Add(1); // 返回新实例,原数据不变
</pre></div></li><li><p>线程本地存储</p>
<ul><li>使用 <code>ThreadLocal&lt;T&gt;</code> 或 <code></code> 为每个线程创建独立副本。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">ThreadLocal&lt;int&gt; threadLocal = new ThreadLocal&lt;int&gt;(() =&gt; 0);
int localValue = threadLocal.Value;
</pre></div></li></ol>
<p class="maodian"></p><h3>1.7 异步与并行</h3>
<ol><li><p><code>async</code>/<code>await</code> 与异步锁</p>
<ul><li>在异步代码中使用 <code>SemaphoreSlim.WaitAsync()</code>。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">private SemaphoreSlim asyncLock = new SemaphoreSlim(1);
await asyncLock.WaitAsync();
try { /* 异步操作资源 */ }
finally { asyncLock.Release(); }
</pre></div></li><li><p>TPL (任务并行库)</p>
<ul><li>使用 <code>Parallel.For</code> 或 <code>Task</code> 时确保资源安全。</li></ul>
<div class="jb51code"><pre class="brush:csharp;">Parallel.For(0, 10, i =&gt;
{
    // 需要内部同步机制
});
</pre></div></li></ol>
<p class="maodian"></p><h3>1.8 选择策略</h3>
<ul><li><strong>简单临界区</strong>:优先使用 <code>lock</code> 或 <code>Monitor</code>。</li><li><strong>读写分离</strong>:使用 <code>ReaderWriterLockSlim</code>。</li><li><strong>高并发读</strong>:不可变对象或并发集合。</li><li><strong>异步场景</strong>:<code>SemaphoreSlim.WaitAsync()</code>。</li><li><strong>跨进程同步</strong>:<code>Mutex</code>。</li></ul>
<p>通过合理选择同步机制,可以平衡性能与线程安全。</p>
<p>到此这篇关于C#多线程访问资源的实现示例的文章就介绍到这了,更多相关C#多线程访问资源内容请搜索琼殿技术社区以前的文章或继续浏览下面的相关文章希望大家以后多多支持琼殿技术社区!</p>
                           
                            <div class="art_xg">
                              <b>您可能感兴趣的文章:</b><ul><li>c#&nbsp;多线程环境下控制对共享资源访问的解决方法</li><li>C#多线程异步执行和跨线程访问控件Helper</li><li>C#&nbsp;多线程中经常访问同一资源可能造成哪些问题</li><li>C#多线程与跨线程访问界面控件的方法</li><li>c#中多线程访问winform控件的若干问题小结</li></ul>
                            </div>

                        </div>
                        <!--endmain-->
頁: [1]
查看完整版本: C#多线程访问资源的实现示例