C# 中实现一个线程持续读取,另一个线程负责写入,且写入时读取线程暂停

实现思路

  1. 暂停信号通过 ManualResetEventSlim 通知读取线程暂停

  2. 暂停确认:读取线程收到暂停信号后,发送确认信号。

  3. 原子性控制:确保写入操作执行期间,读取线程处于完全暂停状态。

  4. 恢复机制写入完成后恢复读取线程。

代码实现

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.

方案特点

  1. 严格同步通过双重信号机制确保写入操作插入的安全性

  2. 无竞态条件 :使用 ManualResetEventSlim 避免多线程竞争。

  3. 可控停止 :通过 _stopRequested 安全终止线程。

相关推荐
2601_9620664934 分钟前
【Sql Server】Update中的From语句,以及常见更新操作方式
android·java·数据库
愤怒的苹果ext1 小时前
MySQL Shell备份恢复数据库
数据库·mysql·备份恢复·mysqlsh
数字新视界3 小时前
DCIM管理系统的技术架构与部署模式详解
数据库·物联网·数据中心·数据中心基础设施管理·dcim管理系统
何以解忧,唯有..3 小时前
Pydantic 介绍与使用:Python 数据校验的现代方案
数据库·python·microsoft
这个DBA有点耶4 小时前
数据库容灾进入“秒级时代”:同城双活架构原理、关键技术选型与落地实践
数据库·架构·dba
2601_962074815 小时前
大数据-264 实时数仓 - Canal MySQL的binlog研究 存储目录 变动信息 配置MySQL
大数据·数据库·mysql
2601_962073815 小时前
大数据-240 离线数仓 - 广告业务 测试 ADS层数据加载 DataX数据导出到 MySQL
大数据·数据库·mysql
Frank_refuel6 小时前
【MYSQL进阶】-> 索引理解
数据库
lv__pf6 小时前
MVCC机制【TL mysql7】
数据库
cqsztech6 小时前
Oracle ai database 26ai rac 通过gold image 更新季度补
数据库·人工智能·oracle