携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第29天,点击查看活动详情
到目前位置,我们一共介绍了5中block
- bufferblock 基础的block
- actionblock 简单消费block,可以再构造中实现委托处理数据
- tansformblock 用来做数据转换,一个inputqueue,一个outputqueue
- tansformmanyblock,一个inputqueue的数据,可以放置多个数据进入outputqueue
- boradcastblock,广播block 下面我们继续介绍几个block
writeonceblock
一次写入block,这个block类似硬件的otp了。它最多只能存储一个数据,一旦这个数据被发送出去以后,这个数据还是会留在Block中,但不会被删除或被新来的数据替换,同样所有的接收者都会收到这个数据的备份。
demo
为了清晰的了解这个demo,我们把前面的广播demo拿过来,稍加改动,看看结果
static WriteOnceBlock<int> bb = new WriteOnceBlock<int>((i) => { return i; });
/// <summary>
/// 广播
/// </summary>
//static BroadcastBlock<int> bb = new BroadcastBlock<int>((i) => { return i; });
/// <summary>
结果
可以看到,我们写入0以后,之后的数据无法写入。
batchblock
该block其实和transformmanyblock可以对比说。
transformmanyblock是可以接收一个数据,放多个数据到output中
batchblock是接收多个数据,满足数量后,放置一个结合体数据到output中
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 BatchBlock<int> bb = new BatchBlock<int>(3);
/// <summary>
/// 消费
/// </summary>
static ActionBlock<int[]> ab = new ActionBlock<int[]>((i) =>
{
string s = string.Empty;
foreach (int m in i)
{
s += m + " ";
}
Console.WriteLine(s);
});
/// <summary>
/// 生产
/// </summary>
static void TestSync()
{
bb.LinkTo(ab);
for (int i = 0; i < 10; i++)
{
bb.Post(i);
}
bb.Complete();
}
/// <summary>
/// main
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.WriteLine("Here We Go!");
TestSync();
Console.ReadLine();
}
}
}
效果
joinblock
joinblock可以看作是batchblock的升级版本。
- batchblock是从一个sourceblock中接收多个数据
- joinblock是从多个sourceblock中接收一个组合数据
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 JoinBlock<int, string> jb = new JoinBlock<int, string>();
/// <summary>
/// 消费
/// </summary>
static ActionBlock<Tuple<int, string>> ab = new ActionBlock<Tuple<int, string>>((i) =>
{
Console.WriteLine(i.Item1 + " " + i.Item2);
});
/// <summary>
/// 生产
/// </summary>
static void TestSync()
{
jb.LinkTo(ab);
for (int i = 0; i < 5; i++)
{
jb.Target1.Post(i);
}
Console.WriteLine("Init Post Over");
for (int i = 5; i > 0; i--)
{
Thread.Sleep(1000);
jb.Target2.Post(i.ToString());
}
Console.WriteLine("String Post Over");
}
/// <summary>
/// main
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.WriteLine("Here We Go!");
TestSync();
Console.ReadLine();
}
}
}
效果
从上面的demo中,我们可以看到。
当int的数据post完毕,joinblock并没有输出,当string开始post后,block才开始输出数据。
joinblock只有当两个sourceblock都有数据,满足条件的时候、才会触发动作。
batchjoinblock
这个名字起的简洁明了,不用我多讲,这个block是batch和join的组合体。具备两者的特质。
上demo
demo
using System;
using System.Threading.Tasks.Dataflow;
using System.Threading.Tasks;
using System.Threading;
using System.Net;
using System.Collections.Generic;
namespace DataFlowDemoS
{
internal class Program
{
/// <summary>
/// 构造
/// </summary>
static BatchedJoinBlock<int, string> bjb = new BatchedJoinBlock<int, string>(3);
/// <summary>
/// 消费
/// </summary>
static ActionBlock<Tuple<IList<int>, IList<string>>> ab = new ActionBlock<Tuple<IList<int>, IList<string>>>((i) =>
{
Console.WriteLine("-----------------------------");
foreach (int m in i.Item1)
{
Console.WriteLine(m);
};
foreach (string s in i.Item2)
{
Console.WriteLine(s);
};
});
/// <summary>
/// 生产
/// </summary>
static void TestSync()
{
bjb.LinkTo(ab);
for (int i = 0; i < 5; i++)
{
bjb.Target1.Post(i);
}
Console.WriteLine("Int Post Over");
for (int i = 5; i > 0; i--)
{
bjb.Target2.Post(i.ToString());
}
Console.WriteLine("String Post Over");
}
/// <summary>
/// main
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
Console.WriteLine("Here We Go!");
TestSync();
Console.ReadLine();
}
}
}
效果
小结
OK,到此为止我们已经介绍完了全部的9种block。简单的罗列:
- bufferblock
- actionblock
- tansformblock
- tansformmanyblock
- boradcastblock
- writeoneceblock
- batchblock
- joinblock
- batchjoinblock