HTML5技术

Asp.net 面向接口可扩展框架之消息队列组件 - xiangji(2)

字号+ 作者:H5之家 来源:H5之家 2016-05-24 10:00 我要评论( )

指令类型 Directive{LookForward = 0 , // 看前看 Left = 1 , // 向左转 Right = 2 , // 向右转 Behind = 3 , // 向后转 Attention = 4 , // 立正 Ease = 5 , // 稍息 EyeRight = 6 , // 向右看齐 EyeLeft = } 解释

指令类型 Directive { LookForward = 0,//看前看 Left = 1,//向左转 Right = 2,//向右转 Behind = 3,//向后转 Attention = 4,//立正 Ease = 5,//稍息 EyeRight = 6,//向右看齐 EyeLeft = }

解释一下:

  A:命令是枚举(也就是int数字)

     B:对于生产者就是接受控制台输入的行文本,如果为“Exit”就结束,否则转化为int

     C:消费者就是接受到一个int值转化为命令枚举(Directive),执行

4、输入几条命令玩玩

Begin 11:54:22.164 请输入指令:1 I say 1 12:04:23.475 士兵1向左转 12:04:23.475 士兵3向左转 12:04:23.475 士兵2向左转 12:04:25.491 请输入指令:2 I say 2 12:04:27.562 士兵2向右转 12:04:27.562 士兵1向右转 12:04:27.593 士兵3向右转 12:04:29.608 请输入指令:3 I say 3 12:04:31.343 士兵1向后转 12:04:31.343 士兵2向后转 12:04:31.343 士兵3向后转 12:04:33.359 请输入指令:0 I say 0 12:04:35.859 士兵1看前看 12:04:35.859 士兵2看前看 12:04:35.859 士兵3看前看 12:04:37.874 请输入指令:9 I say 9 12:04:45.983 士兵1未知指令(9) 12:04:45.983 士兵3未知指令(9) 12:04:45.983 士兵2未知指令(9) 12:04:47.999 请输入指令:2 I say 2 12:04:55.671 士兵1向右转 12:04:55.671 士兵2向右转 12:04:55.671 士兵3向右转 12:04:57.686 请输入指令:Exit I say Exit End

是不是很酷很好玩

A:由于使用的是并行计算(Parallel.ForEach),三个士兵的执行顺序是随机的,这样能更好的利用多cpu资源

B:呵呵,想不到使用电脑练兵这么简单,韩信要是能看到这一幕也只能“甘拜下风”了

二、排队模式

1、排队模式代码和订阅模式稍微不同

Soldier[] soldiers = new Soldier[] { new Soldier { Name = "士兵1" } , new Soldier { Name = "士兵2" } , new Soldier { Name = "士兵3" } , new Soldier { Name = "士兵4" } , new Soldier { Name = "士兵5" } , new Soldier { Name = "士兵6" } , new Soldier { Name = "士兵7" } , new Soldier { Name = "士兵8" } , new Soldier { Name = "士兵9" } };

soldiers

private static void Test1(Soldier[] soldiers) { QueueChannel<int> channel = new QueueChannel<int>(); Produce<int> producer = new Produce<int>() { Instance = new DirectiveAction() { } }; channel.AddProducer(producer); foreach (var item in soldiers) { channel.AddConsumer(new QueueConsumeService<int>() { Instance = item, Timer = new Job.JobTimer { Interval = 1000 } }); } channel.Init(); channel.Start(); while (producer.Run()) { } }

也解读一下:

A:这次队伍壮大了(哈哈,由于前面练兵成效不错,部队迅速扩充了三倍),所以单独出来以便复用

B:这次先定义了频道,而且这次的频道是队列频道(QueueChannel)

C:这里的消费者稍有不同,增加了一个Timer属性,是定时触发器(每1000毫秒触发一次)

     注:现实项目中,在排队模式Timer属性并不是必须的,只是这里演示需要增加一个触发器。因为控制台输入我用来控制生产者了,消费者只能让触发器来控制了

D:另外这里新加一个(channel.Start())用来启动自己的调度和所有生产者和消费者的调度

  这里只有消费者有调度,这行代码对频道和生产者没有影响

E:这个例子里面的生产者(DirectiveAction)和消费者(QueueConsumeService)是直接服用前面例子的

2、和前面例子一样,先输入几个命令玩玩,看看结果

Begin 12:43:04.369 请输入指令:1 I say 1 12:43:09.438 士兵9向左转 12:43:10.642 请输入指令:3 I say 3 12:43:29.751 士兵7向后转 12:43:30.861 请输入指令:8 I say 8 12:43:42.929 士兵4未知指令(8) 12:43:44.898 请输入指令:Exit I say Exit End

生产者生产一个命令,9个消费者随机一个抢到执行

其实就是9个消费者“线程”等待命令执行,大大扩充了消费的效率

当然生产者也可以是多个,也同时生产,这样多多的效率是不是比我们一般同步执行效果高不少啊

PS:但是这里我想到了一个问题,9个消费者9个独立的“线程”,效率确实高,但是如果cpu满载了,别说9个“线程”都不能好好的工作(运行),如果再开多个生产者,大家一起来竞争cpu资源很可能导致问题:

2.1 cpu资源可能出现恶意竞争,cpu大量浪费

    其实线程间不断切换的成本也是挺高的,也是要考虑的因素之一

2.2 cpu资源分配不周

  如果大量消费者使用cpu,生产者可能拿到的cpu不够,生产的"消息"不够消费者使用

      如果大量生产者使用cpu,导致生产堆积,消费者消费不过来也是很糟糕,整体的执行速度还是很慢(甚至还不如单线程)

3、我们看一个优化这个问题的例子代码

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 如何在 ASP.NET Core 中发送邮件 - Savorboard

    如何在 ASP.NET Core 中发送邮件 - Savorboard

    2017-05-02 08:02

  • 十二个 ASP.NET Core 例子 - Savorboard

    十二个 ASP.NET Core 例子 - Savorboard

    2017-04-27 16:01

  • ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    ASP.NET MVC5请求管道和生命周期 - 雪飞鸿

    2017-04-24 08:04

  • 调取百度地图接口,实现取自己的实时位置,然后可以在百度地图上添加信息标注 - QISHUANG

    调取百度地图接口,实现取自己的实时位置,然后可以在百度地图上添加

    2017-04-18 10:02

网友点评