• .NET中使用Channel<T>


    在面对 生产者-消费者 的场景下, netcore 提供了一个新的命名空间 System.Threading.Channels 来帮助我们更高效的处理此类问题,有了这个 Channels 存在, 生产者 和 消费者 可以各自处理自己的任务而不相互干扰,有利于两方的并发处理,这篇文章我们就来讨论下如何使用 System.Threading.Channels。

    为什么要使用 Channels

    可以利用 Channels 来实现 生产者和消费者 之间的解耦,大体上有两个好处:

    • 生产者 和 消费者 是相互独立的,两者可以并行执行。

    • 如果生产者不给力,可以创建多个的生产者,如果消费者不给力,可以创建更多的消费者。

    总的来说,在 生产者-消费者 模式下可以帮助我们提高应用程序的吞吐率。

    创建 channel

    本质上来说,你可以创建两种类型的 channel,一种是有限容量的 bound channel,一种是无限容量的 unbound channel,接下来的问题是,如何创建呢?Channels 提供了两种 工厂方法 用于创建,如下代码所示:

      CreateBounded<T> 创建的 channel 是一个有消息上限的通道。

      CreateUnbounded<T> 创建的 channel 是一个无消息上限的通道。

    l例如

     public class IntervalBackgroundService : BackgroundService
        {
            /// <summary>
            /// 
            /// </summary>
            /// <param name="stoppingToken"></param>
            /// <returns></returns>
            protected override Task ExecuteAsync(CancellationToken stoppingToken)
            {
                _ = SendQueue(stoppingToken);
                return Task.CompletedTask;
            }
            async Task SendQueue(CancellationToken stoppingToken)
            {
                while (!stoppingToken.IsCancellationRequested && await ThreadChannels.IsWait())
                {
                    ReservationParam pos = ThreadChannels.Take();
                    if (pos == null)
                    {
                        continue;
                    }
                    await new MessageFacade().SendReservationMsg(pos);
                };
            }
        }
    /// <summary>
        /// 通道是线程安全的
        /// </summary>
        public class ThreadChannels
        {
            public static Channel<ReservationParam> threadChannels { get; set; } = Channel.CreateUnbounded<ReservationParam>();
    
            public static bool Add(ReservationParam msg)
            {
                if (threadChannels == null)
                {
                    threadChannels = Channel.CreateUnbounded<ReservationParam>();
                }
                return threadChannels.Writer.TryWrite(msg);
            }
            public static ReservationParam Take()
            {
                if (threadChannels == null)
                {
                    threadChannels = Channel.CreateUnbounded<ReservationParam>();
                }
                threadChannels.Reader.TryRead(out ReservationParam pos);
                return pos;
            }
            public async static Task<bool> IsWait()
            {
                if (threadChannels == null)
                {
                    threadChannels = Channel.CreateUnbounded<ReservationParam>();
                }
                return await threadChannels.Reader.WaitToReadAsync();
            }
        }
  • 相关阅读:
    xshell中的nohup与&的含义
    eclipse启动服务报错:Exception in thread "main" java.lang.UnsupportedClassVersionError: org/apache/maven/cli/MavenCli : Unsupported major.minor version 51.0
    关于MyEclipse启动报错:Error starting static Resources;下面伴随Failed to start component [StandardServer[8005]]; A child container failed during start.的错误提示解决办法.
    组件/服务之间的通信-事件广播和订阅可以有效减少全局变量
    #css3# 可以多背景图设置
    #RXJS# 基础
    #TS# get/set
    #css3# : vs ::
    #css3# box-sizing
    #DOM# 最佳实践:head里面标签的顺序
  • 原文地址:https://www.cnblogs.com/netlock/p/14911596.html
Copyright © 2020-2023  润新知