首页 新闻 会员 周边 捐助

定时器,触发问题

0
悬赏园豆:30 [已解决问题] 解决于 2016-12-21 16:48

 我有一个 队列  ,当我  添加 数据后 ,后台 会 自动  获取  队列 数据  进行 操作 ,求 实际 生产 环境 可以 使用的 思路

元点之始的主页 元点之始 | 初学一级 | 园豆:6
提问于:2016-12-21 13:13
< >
分享
最佳答案
1

这个.....只要是队列都能达到你的需求吧。无非就是push/pull的差别而已。

收获园豆:30
Daniel Cai | 专家六级 |园豆:10424 | 2016-12-21 14:09

额,是  --------    自动 ----- ,因为处理每条数据 耗时很久

元点之始 | 园豆:6 (初学一级) | 2016-12-21 14:11

@元点之始: 当然是自动啊,最简单的pull模式,拉到消息就开始处理,拉不到消息就在那边block住(或一个死循环进去下一个周期判断队列是否有消息)

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 14:37

@Daniel Cai: 不懂。。。。。

元点之始 | 园豆:6 (初学一级) | 2016-12-21 15:05

@Daniel Cai: 我需要建立 一个服务 定时 执行 吗

元点之始 | 园豆:6 (初学一级) | 2016-12-21 15:20

@元点之始: 随便找个队列了解下吧,demo很多的,基本所有的队列最基本的实例都满足你的需求。

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 15:20

@元点之始: 不需要定时执行,在pull模式下,你的服务会不停的问队列有没有消息,有的话你就可以直接消费掉。

push模式下队列会直接触发你的消费者的消费方法。

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 15:23

@Daniel Cai:  其实我就是想知道 pull 模式 是怎么 实现的, 你 说的 这个 不停地 问 队列  应该 就是 一个 While(true) 吧。。。。

元点之始 | 园豆:6 (初学一级) | 2016-12-21 15:26

@元点之始: 

如果队列会block住就类似下面的

xxxMessage message;

while(queue.TryDequeue(out message))

{

  process your message here;

}

如果队列的方法不block就变成你说的while(true)了

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 15:28

@Daniel Cai:  额,好吧,我 这么 说吧。。。 我 把 消息 存入了 数据库 , 什么 时候  去 执行  这个 While( true) ..  因为 别人 把 数据 添加 完 就没有 关系了 。。。  

元点之始 | 园豆:6 (初学一级) | 2016-12-21 15:34

@元点之始: 这个和队列有什么关系么?我不太明白你的需求是什么。

如果你是希望在数据落地后触发某种逻辑,那么你在数据落地时发送消息就可以了。

如果是其他人只数据落地,你期望在数据落地后触发你的某些逻辑的话可以做定时轮询db获取数据变化后来实现。

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 15:40

@Daniel Cai: 我写个 window 服务 可以吗? 服务 启动后 就会 不停地 问 数据 库 ,如果 有数据 ,就进行处理

元点之始 | 园豆:6 (初学一级) | 2016-12-21 15:46

@元点之始: 可以的,但这种轮询比较蛋疼,数据量大了后如果查询语句写的不好或者根本不走索引会给db带来负担。

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 15:48

@Daniel Cai:  队列 用的 msmq,别人 把数据 存到这里面,让我 去取,但是我 不知道  什么 时候开始执行, 就想  用这种 方法  隔一段时间  处理 一次

元点之始 | 园豆:6 (初学一级) | 2016-12-21 15:52

@元点之始: msmq就更简单了,就是个pull过程,你如果直接用framework自带的msmq相关处理方法的话在队列没有消息时是block住的(会超时,需要额外catch后再dequeue),如果你想控制节奏就在每条消息处理完后sleep下(但理论上这种sleep是没意义的)。

你所谓的开始实际上是当消息已经持久化后(msmq),你这边就会立即收到消息了。所以你不用考虑什么定时器。

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 15:57

@Daniel Cai:  是的,1. 我 不知道 怎么 运行 我的这个 程序 ,以什么方式 运行我的 代码?所以 想 单独 写个 服务   还是  在  网站 项目中  添加 类库  2. 我不清楚 用什么 方式 去   判断 ,去取 msmq 数据 ,是不停 循环 ,还是  在  添加  数据时  会 给我  一个  触发 的    信息

元点之始 | 园豆:6 (初学一级) | 2016-12-21 16:06

@元点之始: 

1.windows 服务,这个比较简单,vs中建个windows服务的项目默认的代码已经具备了windows服务的雏形了,你只需要在onstart和onstop中分别开始取消息和停止取消息(清理工作)即可

2.对于队列而言,你不用关心队列中是不是有数据,针对msmq而言,你只需要指明你所需要消耗消息的队列,然后receive(接受并删除消息,和dequeue一个意思,如果没有消息则会一直block在这行代码直至超时),什么时候收到完全取决于什么时候发送消息。

msmq中如果是一条条的处理消息需要写个死循环去拉取(或者根据条件做循环),而你receive这个方法执行后就可以获取到队列中的数据了(注意如果队列中长时间没消息会出现超时情况,需要catch掉)。

这里其实你应该比较关心的是数据的反序列化过程要和发送消息的序列化过程匹配以及是否为事务性队列

在消耗消息时这里就属于群魔乱舞了,从单线程一个个的处理到多进程多线程加各种乱七八糟的控制都有,这里主要看你的实际业务需求(比如数据安全性等)。

建议你直接找个msmq的demo代码看下并实际用下,ms的东西上手都很简单的。

msmq中整个流程如下:

1.生产者发送消息到队列

2.队列持久化完毕(磁盘)

3.消费者的receive方法会获取到最老的一条消息(fifo)

如果生产速度大于消费速度,则消息会逐渐在队列中积压(需要避免,一般实际场景中通过对消费者横向扩容解决)

当队列中消息被处理完毕,则消费者的receive方法被block住(有超时)

4.消费者一旦使用receive方法收到消息,则收到的消息会在队列中删除,因此不会出现多消费者消费同一消息的情况。

5.处理完消息再次receive后面的消息。

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 16:32

@Daniel Cai:  大神 ,多谢了  。。  取数据 的时候   用 死循环  , 还有  消息 为空 时 block 住  这样 会不会 有 性能 问题。。。。 

元点之始 | 园豆:6 (初学一级) | 2016-12-21 16:44

@元点之始: 不会,你都没事情做了是不是block住又有什么区别?

其他各种队列都会有类似处理(activemq,rabbitmq等)

Daniel Cai | 园豆:10424 (专家六级) | 2016-12-21 16:46

@Daniel Cai:  跪谢大神。。。。

元点之始 | 园豆:6 (初学一级) | 2016-12-21 16:47
其他回答(1)
0

你的需求:加个定时器做个一个监听器定时监听一个消息队列,只要队列中一有Message就去取吗?

如果是这个需求,

思路:先定义一个定时器,定时取Message,这里有个地方需要注意,当一个定时器启动触发一个取Message的操作还没结束时,另一个定时器又启动并触发一个新的取Message操作,这样会抛出异常。

解决方案:第一次通过定时器启动取Message时,可以在开始取Message处关闭定时器,接着通过判断队列中的消息数目MessageCount,当消息数目为0时,也就是消息刚好取完了,再开启定时器,这样就可以实时地监听队列。

办法有点笨,不过应该可以满足你的需求。

PS:建议线程处理

~扎克伯格 | 园豆:1923 (小虾三级) | 2016-12-21 15:58

取别人 放在 msmq 队列中  的 数据, 我 要 写代码 ,需要放在什么 中可以执行 ? 需要 写个window 服务吗?

支持(0) 反对(0) 元点之始 | 园豆:6 (初学一级) | 2016-12-21 16:11

@元点之始: 如果你要写服务端,并且要将队列中数据作进一步处理的话,可以写个windows服务。

支持(0) 反对(0) ~扎克伯格 | 园豆:1923 (小虾三级) | 2016-12-21 16:16
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册