System.Threading.Channels 进程内发布订阅

首先,Channel本质上是.net中的一种新的集合类型,它与现有的Queue<T>类型非常相似,当然也有不同之处。

System.Threading.Channels 是.NET Core 3.0 后推出的新的集合类型, 具有异步API,高性能,线程安全等特点,它可以用来做消息队列,进行数据的生产和消费, 公开的 Writer 和 Reader api对应消息的生产者和消费者,也让Channel更加的简洁和易用,与Rabbit MQ 等其他队列不同的是,Channel 是进程内的队列

 

namespace TestWebApplication.Channels
{
    public class ChannelAccessor<TModel>
    {
        private static readonly Lazy<ChannelAccessor<TModel>> lazy = new Lazy<ChannelAccessor<TModel>>(() => new ChannelAccessor<TModel>());
        private ChannelReader<TModel> _reader;
        private ChannelWriter<TModel> _writer;
        public ChannelReader<TModel> ChannelReader => _reader;
        public ChannelWriter<TModel> ChannelWriter => _writer;
        private ChannelAccessor()
        {
            Channel<TModel> channel = Channel.CreateBounded<TModel>(new BoundedChannelOptions(100)
            {
                FullMode = BoundedChannelFullMode.DropOldest,
            });
           _reader = channel.Reader;
           _writer = channel.Writer;
        }
        public static ChannelAccessor<TModel> CreateInstance => lazy.Value;
    }
}

  

WaitToReadAsync 等待信道可读

ReadAsync(stoppingToken) 读取信道

  public class ChannelHostService : BackgroundService
  {
      protected override async Task ExecuteAsync(CancellationToken stoppingToken)
      {
          await Task.Factory.StartNew(async () =>
          {
              //WaitToReadAsync 等待信道可读
              while (await ChannelAccessor<string>.CreateInstance.ChannelReader.WaitToReadAsync(stoppingToken))
              {
                  string msg = await ChannelAccessor<string>.CreateInstance.ChannelReader.ReadAsync(stoppingToken);
                  await Console.Out.WriteLineAsync($" 消息为: {msg}");
              }              
          }, TaskCreationOptions.LongRunning);
      }
  }

  

测试可用

    [Route("api/[controller]")]
    [ApiController]
    public class ChannelsController : ControllerBase
    {
        [HttpGet]
        public async Task<IActionResult> Get(string msg)
        {
            await ChannelAccessor<string>.CreateInstance.ChannelWriter.WriteAsync(msg);

            return Ok(msg);
        }
        [HttpGet("Recive")]
        public async Task<IActionResult> Recive()
        {

            string msg = await ChannelAccessor<string>.CreateInstance.ChannelReader.ReadAsync();

            return Ok(msg);
        }
    }

参考

C# Channel 简单实现消息队列的发布、订阅 - 天才卧龙 - 博客园 (cnblogs.com)

C#并发编程秘籍:驾驭System.Threading.Channels,解锁异步消息传递新境界——代码实战与注释深度解析-CSDN博客

 

posted on 2024-06-12 10:39  是水饺不是水饺  阅读(36)  评论(0)    收藏  举报

导航