c# 高并发的几种方式(五)

145 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情 

承接上一章,我们知道数据流的处理是将数据分为块数据,并进行网格处理。上一章我们介绍了两种block:

  • bufferblock
  • actionblock

接下来我们继续介绍block

transformblock

transformblock提供数据的转换功能,再内部维护了两个queue,一个接收,一个输出。

  • 数据进入block中后,存入inputqueue中
  • block进行数据转换
  • 转换成功数据放入outputqueue中
  • outputqueue中数据为0,才会响应completion.wait方法

demo

using System;
using System.Threading.Tasks.Dataflow;
using System.Threading.Tasks;
using System.Threading;
using System.Net;

namespace DataFlowDemoS
{
    internal class Program
    {
        /// <summary>
        /// 构造
        /// </summary>
        public static TransformBlock<string, string> tfblock = new TransformBlock<string, string>((name) =>
        {
            switch (name)
            {
                case "lilei":
                    return $"name:{name} age:11";
                case "hanmei":
                    return $"name:{name} age:22";
                default:
                    return "noting";
            }
        });
        /// <summary>
        /// 生产
        /// </summary>
        public static void GetAgeByName()
        {
            tfblock.Post("lilei");
            tfblock.Post("hanmei");
            tfblock.Complete();

            Console.WriteLine(tfblock.Receive());
            Console.WriteLine(tfblock.Receive());

            tfblock.Completion.Wait();
        }
       
        /// <summary>
        /// main
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.WriteLine("Here We Go!");
            GetAgeByName();
            Console.ReadLine();
        }
    }
}

结果

image.png

transformmanyblock

这个block比我们上一个转换block多了一个many。顾名思义,该block可以将一个input数据处理完毕,放入多个outputqueue中去。还是老样子,直接上demo
linkto 是吧多个数据块连接起来,进行流处理

demo

using System;
using System.Threading.Tasks.Dataflow;
using System.Threading.Tasks;
using System.Threading;
using System.Net;

namespace DataFlowDemoS
{
    internal class Program
    {
        /// <summary>
        /// 构造
        /// </summary>
        static TransformManyBlock<int, int> tmb = new TransformManyBlock<int, int>((i) => { return new int[] { i, i + 1 }; });
        /// <summary>
        /// action block
        /// </summary>
        static ActionBlock<int> ab = new ActionBlock<int>((i) => Console.WriteLine(i));
        /// <summary>
        /// 生产
        /// </summary>
        public static void TestSync()
        {
            tmb.LinkTo(ab);
            for (int i = 0; i < 4; i++)
            {
                tmb.Post(i);
            }
            Console.WriteLine("Finished post");
        } 
        /// <summary>
        /// main
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.WriteLine("Here We Go!");
            TestSync();
            Console.ReadLine();
        }
    }
}

结果

image.png

  • 我们将数据放入 tansformmanyblock中
  • block从input中获取一个数据,并放入多个数据
  • 一个i,一个i+1
  • 之后流进行actionblock处理,控制台输出。

broadcastblock

看名字,这个block是广播作用。他的作用是让和他所有相连接的block接收到数据的副本。该block并不会向我们之前所介绍的block一样,把数据保存,它仅仅会保留最后一个数据,之前的数据都会被清除。
来吧,demo起来。

demo

using System;
using System.Threading.Tasks.Dataflow;
using System.Threading.Tasks;
using System.Threading;
using System.Net;

namespace DataFlowDemoS
{
    internal class Program
    {
        /// <summary>
        /// 广播
        /// </summary>
        static BroadcastBlock<int> bb = new BroadcastBlock<int>((i) => { return i; });
        /// <summary>
        /// 处理
        /// </summary>
        static ActionBlock<int> action1 = new ActionBlock<int>((i) => Console.WriteLine($"action1:[{i}] "));
        static ActionBlock<int> action2 = new ActionBlock<int>((i) => Console.WriteLine($"action2:[{i}]"));
        static ActionBlock<int> action3 = new ActionBlock<int>((i) => Console.WriteLine($"action3:[{i}] "));
        /// <summary>
        /// 生产
        /// </summary>
        static void TestSync()
        {
            bb.LinkTo(action3);
            bb.LinkTo(action2);
            bb.LinkTo(action1);

            for (int i = 0; i < 4; i++)
            {
                bb.Post(i);
            }
        }
        /// <summary>
        /// main
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            Console.WriteLine("Here We Go!");
            TestSync();
            Console.ReadLine();
        }
    }
}

效果

image.png

本章我们介绍了三种block:tansformblock,tansformmanyblock和broadcastblock

  • tansformblock 用来做数据转换,一个inputqueue,一个outputqueue
  • tansformmanyblock,一个inputqueue的数据,可以放置多个数据进入outputqueue
  • boradcastblock,广播block,不会保存数据