实现思路
-
暂停信号 :通过
ManualResetEventSlim
通知读取线程暂停。 -
暂停确认:读取线程收到暂停信号后,发送确认信号。
-
原子性控制:确保写入操作执行期间,读取线程处于完全暂停状态。
-
恢复机制 :写入完成后恢复读取线程。
代码实现
cs
using System;
using System.Threading;
public class ReadWriteController
{
// 控制读取线程暂停和恢复的信号
private readonly ManualResetEventSlim _pauseRequest = new ManualResetEventSlim(false);
// 读取线程确认已暂停的信号
private readonly ManualResetEventSlim _pausedConfirmed = new ManualResetEventSlim(false);
// 停止读取线程的标志
private volatile bool _stopRequested = false;
// 读取线程的循环任务
public void ReadLoop()
{
while (!_stopRequested)
{
// 检查是否需要暂停
if (_pauseRequest.IsSet)
{
// 确认已暂停,并等待恢复信号
_pausedConfirmed.Set();
_pauseRequest.Wait();
_pausedConfirmed.Reset();
}
// 模拟读取操作(此处可替换为实际业务逻辑)
Console.WriteLine($"[Read] {DateTime.Now:HH:mm:ss.fff} - Reading data...");
Thread.Sleep(1000); // 模拟耗时操作
}
Console.WriteLine("[Read] Thread stopped.");
}
// 写入操作的外部触发方法
public void WriteCommand()
{
// 发送暂停请求
_pauseRequest.Set();
Console.WriteLine("[Write] Pause request sent.");
// 等待读取线程确认暂停
_pausedConfirmed.Wait();
Console.WriteLine("[Write] Read thread paused. Starting write operation...");
// 模拟写入操作(此处可替换为实际业务逻辑)
Thread.Sleep(500); // 模拟耗时操作
Console.WriteLine($"[Write] {DateTime.Now:HH:mm:ss.fff} - Write completed.");
// 恢复读取线程
_pauseRequest.Reset();
Console.WriteLine("[Write] Read thread resumed.");
}
// 停止所有线程
public void Stop()
{
_stopRequested = true;
_pauseRequest.Set(); // 确保读取线程退出等待
}
}
// 使用示例
public class Program
{
public static void Main()
{
var controller = new ReadWriteController();
// 启动读取线程
var readThread = new Thread(controller.ReadLoop);
readThread.Start();
// 模拟写入操作(每隔3秒触发一次)
for (int i = 0; i < 3; i++)
{
Thread.Sleep(3000);
controller.WriteCommand();
}
// 停止所有线程
controller.Stop();
readThread.Join();
Console.WriteLine("Main thread exited.");
}
}
代码解析
1. 控制信号定义
-
_pauseRequest
:写入线程通过Set()
发送暂停请求,读取线程通过Wait()
阻塞自身。 -
_pausedConfirmed
:读取线程暂停后通过Set()
通知写入线程,确保写入操作安全执行。
2. 读取线程逻辑
cs
while (!_stopRequested)
{
if (_pauseRequest.IsSet)
{
_pausedConfirmed.Set(); // 确认已暂停
_pauseRequest.Wait(); // 等待恢复信号
_pausedConfirmed.Reset(); // 重置确认信号
}
// 执行读取操作...
}
-
每次循环检查暂停请求。
-
若收到暂停信号,立即确认并阻塞自身,直到写入完成。
3. 写入线程逻辑
cs
public void WriteCommand()
{
_pauseRequest.Set(); // 发送暂停请求
_pausedConfirmed.Wait(); // 等待读取线程确认暂停
// 执行写入操作...
_pauseRequest.Reset(); // 恢复读取线程
}
-
写入前确保读取线程已完全暂停。
-
写入完成后恢复读取线程。
运行效果
[Read] 14:25:03.456 - Reading data...
[Read] 14:25:04.457 - Reading data...
[Write] Pause request sent.
[Write] Read thread paused. Starting write operation...
[Write] 14:25:05.457 - Write completed.
[Write] Read thread resumed.
[Read] 14:25:05.958 - Reading data...
[Read] 14:25:06.959 - Reading data...
...
Main thread exited.
方案特点
-
严格同步 :通过双重信号机制确保写入操作插入的安全性。
-
无竞态条件 :使用
ManualResetEventSlim
避免多线程竞争。 -
可控停止 :通过
_stopRequested
安全终止线程。