using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
 
namespace TDFDemo
{
class Program
{
static void Main(string[] args)
{
new Program().Run();
}
 
private async void Run()
{
var bus = new Bus();
 
// Inline handler
var s1 = bus.Subscribe<Message>(message => Console.WriteLine("Inline Handler 1: {0}", message.Content));
 
// Inline handler factory
var s2 = bus.Subscribe<Message>(() => new MessageHandler().Handle);
 
// Automatic handler subscription
var s3 = bus.Subscribe<Message, MessageHandler>();
 
for (int i = 0; i < 10; i++)
{
await bus.SendAsync(new Message("Message " + i));
}
 
// Unsubscribe the second handler
bus.Unsubscribe(s2);
 
Thread.Sleep(1000);
 
// Cancellation support
 
Console.WriteLine("\nSecond Burst:");
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
 
for (int i = 0; i < 10; i++)
{
await bus.SendAsync(new Message("Message " + i), token);
 
if (i == 5)
{
tokenSource.Cancel();
break;
}
}
 
Console.ReadLine();
}
}
 
public class Message
{
public DateTime TimeStamp { get; private set; }
public string Content { get; private set; }
 
public Message(string content)
{
Content = content;
TimeStamp = DateTime.UtcNow;
}
}
 
public interface IHandle<TMessage>
{
void Handle(TMessage message);
}
 
public class MessageHandler : IHandle<Message>
{
public void Handle(Message message)
{
Console.WriteLine("Message Handler Received: {0}", message.Content);
}
}
 
public class Bus
{
private readonly BroadcastBlock<object> broadcast =
new BroadcastBlock<object>(message => message);
 
private readonly ConcurrentDictionary<Guid, IDisposable> subscriptions
= new ConcurrentDictionary<Guid, IDisposable>();
 
public Task<bool> SendAsync<TMessage>(TMessage message, CancellationToken cancellationToken)
{
return broadcast.SendAsync(message, cancellationToken);
}
 
public Guid Subscribe<TMessage>(Action<TMessage> handlerAction)
{
var handler = new ActionBlock<object>(
message => handlerAction((TMessage)message),
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 2 }
);
 
var subscription = broadcast.LinkTo(
handler,
new DataflowLinkOptions { PropagateCompletion = true },
message => message is TMessage
);
 
return AddSubscription(subscription);
}
 
public void Unsubscribe(Guid subscriptionId)
{
IDisposable subscription;
if (subscriptions.TryRemove(subscriptionId, out subscription))
{
subscription.Dispose();
}
}
 
private Guid AddSubscription(IDisposable subscription)
{
var subscriptionId = Guid.NewGuid();
subscriptions.TryAdd(subscriptionId, subscription);
return subscriptionId;
}
}
 
public static class BusExtensions
{
public static Task<bool> SendAsync<TMessage>(this Bus bus, TMessage message)
{
return bus.SendAsync<TMessage>(message, CancellationToken.None);
}
 
public static Guid Subscribe<TMessage>(this Bus bus, Func<Action<TMessage>> handlerActionFactory)
{
return bus.Subscribe<TMessage>(message => handlerActionFactory().Invoke(message));
}
 
public static Guid Subscribe<TMessage, THandler>(this Bus bus) where THandler : IHandle<TMessage>, new()
{
return bus.Subscribe<TMessage>(message => new THandler().Handle(message));
}
}
}

tpl demo的更多相关文章

  1. Thinkcmf 二次开发

    一.   创建模板 demo 1 Tpl下创建demo文件-----后台启用新的模板 (网站信息--模板方案) 2 在模板在tpl/demo目录下创建Portal目录,然后在Portal目录下创建in ...

  2. 6个强大的AngularJS扩展应用

    本文链接:http://www.codeceo.com/article/6-angularjs-extension.html本文作者:码农网 – 小峰 AngularJS现在非常热门,是Google推 ...

  3. 迷你版 smarty --模板引擎和解析

    http://blog.ipodmp.com/archives/php-write-a-mini-smarty-template-engine/ 迷你版Smarty模板引擎目录结构如下: ① 要开发一 ...

  4. 从DOM操作看Vue&React的前端组件化,顺带补齐React的demo

    前言 接上文:谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo 上次写完博客后,有朋友反应第一内容有点深,看着迷迷糊糊:第二是感觉没什么使用场景,太过业务化,还不如直接写Vue ...

  5. 谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo

    前言 前端已经过了单兵作战的时代了,现在一个稍微复杂一点的项目都需要几个人协同开发,一个战略级别的APP的话分工会更细,比如携程: 携程app = 机票频道 + 酒店频道 + 旅游频道 + ..... ...

  6. /Home/Tpl/Equipment/rangeIndex.html 里调用魔板

    <pre name="code" class="html">demo:/var/www/DEVOPS# vim ./Home/Tpl/Equipme ...

  7. GatewayWorker+Laravel demo

    GatewayWorker 结合 Laravel 使用的简单案例,重点是在Laravel中使用GatewayClient发送消息 主要流程:GatewayWorker主要负责推送消息给客户端但不接受客 ...

  8. 通过一个demo了解Redux

    TodoList小demo 效果展示 项目地址 (单向)数据流 数据流是我们的行为与响应的抽象:使用数据流能帮我们明确了行为对应的响应,这和react的状态可预测的思想是不谋而合的. 常见的数据流框架 ...

  9. 很多人很想知道怎么扫一扫二维码就能打开网站,就能添加联系人,就能链接wifi,今天说下这些格式,明天做个demo

    有些功能部分手机不能使用,网站,通讯录,wifi基本上每个手机都可以使用. 在看之前你可以扫一扫下面几个二维码先看看效果: 1.二维码生成 网址 (URL) 包含网址的 二维码生成 是大家平时最常接触 ...

随机推荐

  1. ubuntu12.04的vim配置

    ubuntu12.04中使用的vim的版本不支持像语法高亮和文件类型检测等配置 #sudo apt-get install vim vim默认的配置使用起来还不能让人满意,还需要自己配置默认配置文件是 ...

  2. iOS开发中一些常用的方法

    1.压缩图片 #pragma mark 处理图片 - (void)useImage:(UIImage *)image { NSLog(@"with-----%f heught-----%f& ...

  3. 深入理解Linux操作系统守护进程的意义

    Linux服务器在启动时需要启动很多系统服务,它们向本地和网络用户提供了Linux的系统功能接口,直接面向应用程序和用户.提供这些服务的程序是由运行在后台的守护进程(daemons)来执行的.守护进程 ...

  4. WPF柱状图(支持数据库动态更新)之组件的数据动态化

    WPF柱状图(支持数据库动态更新) 在这片文章中我们介绍了如何将柱状图包装成一个组件,将这个组件的属性对外开放和组件的外部属性根内部属性绑定以及非轮询动态更新数据的方式. 非轮询更新数据感觉介绍的不够 ...

  5. UBUNTU 关闭iptables的方法

    UBUNTU没有相关的直接命令 请用如下命令 iptables -P INPUT ACCEPT iptables -P OUTPUT ACCEPT tables是内核模块删除不了滴现查看一下你ipta ...

  6. 转:Oracle EBS 寄售业务总结

    转自:http://blog.vsharing.com/nicr/A1359214.html 总述: 须通过一揽子采购协议(BPA)明确采购方与供应商之间的寄售关系,及各种协议条款: 通过来源补充规则 ...

  7. Ganymed SSH-2 for Java

    Ganymed SSH-2 for Java是一个纯Java实现的SHH2库,官网为http://www.ganymed.ethz.ch/ssh2/,最新的更新时间为2006年10月,在用之前,请仔细 ...

  8. Unity3D 之NGUI各种脚本及应用

    这里来介绍一下NGUI的各种脚本的作用,以便以后需要某种效果的时候,去添加相应的脚本去实现效果 UIButton --> 按钮脚本 UIPanel   --> 面板脚本 UIToggle  ...

  9. WebView支持特效,页面内跳转(转载!)

    webView = (WebView) findViewById(R.id.lottery_webview); webView.getSettings().setJavaScriptEnabled(t ...

  10. nvidia安装与卸载方式

    第1种方法:.最好的方式不是手动安装官方驱动(手动安装官方驱动无法使用gpu,而且无法启用3d,同时无法生效,所以最好采用此种方法),而是使用bumblebee-nvidia安装,不过要先添加x-sw ...