C#中的System.Timers.Timer

名人堂再聚首 2012-12-27 09:40:58
大家好!

我现在有个问题想向大家请教下:
我用C#4.0做了一个后台Windows服务,其中使用到了System.Timers的Timer对象,我要实现的功能如下:

1、有一台DVR硬盘摄像机,它有几个频道,每个频道都有一个摄像头,当每一个摄像头捕捉到异常情况时就会发出电邮。

2、在Windows服务中我使用了一个Timer对象定时接收从DVR发出的邮件(包括邮件内容,邮件发出的时间),并把它存放到数据库中。

3、同时我启用了另一个Timer对象来分析所接收到的邮件,比如我把这个Timer的Interval设置为30秒,则它每隔30秒就会分析在过去30秒内收到了哪些邮件,也就是从数据库中查询过去30秒内收到了哪些邮件(根据邮件的发出的时间查询),如果我将它的Interval设置为60秒,则它必须分析在过去60秒内接收到了哪些邮件,以此类推。

4、但现在的问题是,我想知道在过去30秒内是否有不同的摄像头同时都发出了邮件,比如DVR连接两个摄像头,我想知道,某一个30秒内这两个摄像头是否都发出了警报邮件,因为定时器是定时工作的,有可能所分析的数据并不是准确的,或者是我使用的方法不对。例如,摄像头1在12:55:10时发出了警报邮件,摄像头2在12:55:31时发出了警报邮件,这两个邮件确实是在30秒范围内,而我的定时器有可能是12:55:20时才经过了一个定时周期,所以如果从12:55:20算起,在过去的30秒内就只有12:55:10这个符合条件,就把12:55:31这个时间给漏掉了,但实际情况是:摄像头1和摄像头2两个发出警报邮件的时间间隔是在30秒之内的,这个问题不知道有没有什么好的方法,望各位赐教,谢谢了!
...全文
404 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
铜臂阿铁木 2012-12-28
  • 打赏
  • 举报
回复
引用 12 楼 jmmx 的回复:
引用 11 楼 sunzongbao2007 的回复:引用 10 楼 sunzongbao2007 的回复: 这时候CD可以标记为未读,AB因为已经算作警报了,所以可以标记为已读了。 就是只把跳变作为问题发生点,跳变后依然在检测序列中。 谢谢你!经过你的提示,我现在已经有思路了,现正在测试,如果有其他问题我会再向你请教,我会尽快结贴给分!
注意繁化简,不要凡事都往规范化上面靠,有的时候,程序稳定可用高效该是追求的根本。 如果不需要扩展,写程序来实现都是多余的。 几根线+一个芯片就够了……
名人堂再聚首 2012-12-28
  • 打赏
  • 举报
回复
引用 11 楼 sunzongbao2007 的回复:
引用 10 楼 sunzongbao2007 的回复: 这时候CD可以标记为未读,AB因为已经算作警报了,所以可以标记为已读了。 就是只把跳变作为问题发生点,跳变后依然在检测序列中。
谢谢你!经过你的提示,我现在已经有思路了,现正在测试,如果有其他问题我会再向你请教,我会尽快结贴给分!
铜臂阿铁木 2012-12-28
  • 打赏
  • 举报
回复
引用 10 楼 sunzongbao2007 的回复:
这时候CD可以标记为未读,AB因为已经算作警报了,所以可以标记为已读了。
就是只把跳变作为问题发生点,跳变后依然在检测序列中。
铜臂阿铁木 2012-12-28
  • 打赏
  • 举报
回复
引用 9 楼 jmmx 的回复:
引用 7 楼 sunzongbao2007 的回复:不要去直接的查过去三十秒。 而是这样: 你不是有数据库么, 检查过的邮件加标记,每次都检查新增的邮件。 比如: 第一个周期你接收到了 A B C D四封邮件, 检查第一个周期,这样标记ABC为已经检查。 D作为下一周期的开头。 第二个周期收到E, 检查E和D的时间间隔, 将D标记为已读,E作为下一周期的开头……循环下……
那个ABCD作为监察条件,如果都是5秒内发来的信,有如下情况: 1.ABCD都是M摄像头发出,这样你只需要留住最后一个D作为未读,其余是已读即可,因为ABC虽然距离D近,但是只需要D就可以判断后面的EFGH是否符合警报了,所以只留D即可; 2.ABCD中ACD是M摄像头发出,B是N摄像头发出,这时候只需AB即可判断出了问题,跳变是A->B 和 B->C(这时候需要你们自己的设计了,因为AB算问题,BC也算是问题,BD也算,这时候我觉得,只将最近一次摄像头跳变作为问题发生时间,也就是B),这时候CD可以标记为未读,AB因为已经算作警报了,所以可以标记为已读了。 记住,你的这个警报程序其实就是信号跳变检测,不用程序用纯电路也能做出来的,所以你只需要模拟电路跳变检测就行了。 10秒请求POP3服务器太频繁, 如果你的程序不要求实时警报不要设置这么短。 另外还有个办法, 因为你的数据库只是Add邮件信息和Search邮件信息,你可以用“多进程并发”的方法。写一个邮件更新程序,只做“读取POP3服务器” “封装” “插入数据库”三个操作, 然后运行10个20个的(最好别在同一台机器上,IP可能会被POP3封锁,性能也会下降),这样即使每个请求时间间隔设置成1分钟,实时程度也会比较高的,最坏是那些打开的程序完全并行执行,更新间隔变成一分钟,最好情况是更新间隔3秒(打开20个的话)。 这个方法是临时想的,你考察一下用不用,如果POP3不锁频繁访问IP,你的10秒间隔也没啥。
名人堂再聚首 2012-12-28
  • 打赏
  • 举报
回复
引用 7 楼 sunzongbao2007 的回复:
不要去直接的查过去三十秒。 而是这样: 你不是有数据库么, 检查过的邮件加标记,每次都检查新增的邮件。 比如: 第一个周期你接收到了 A B C D四封邮件, 检查第一个周期,这样标记ABC为已经检查。 D作为下一周期的开头。 第二个周期收到E, 检查E和D的时间间隔, 将D标记为已读,E作为下一周期的开头……循环下去。
铜臂阿铁木,你好! 谢谢你耐心的回答,我现在是这样做的: 我的系统里设定了一些条件,比如条件1的触发依据是:摄像头1和摄像头2必须同时发出了警报邮件(并且在指定的时间内,例如30秒内),条件2的触发依据是:摄像头3和摄像头4必须同时发出了警报(并且在指定的时间内,例如45秒内)。 现在是:系统每接收到一封新邮件,我就会查询以当前的邮件的发送时间减去30秒(也可以是40秒或其他)为起始时间,当前邮件的发送时间为截止时间,看这个时间段内的邮件是否包含了某个条件需要检测的警报邮件。这样做可以检测到相应的条件是否满足,但有一个问题是:如果邮件的发送时间间隔比较短的话,例如5秒钟发一封,在查询的时候就会包含很多条邮件,但又不能加标记为已读,因为有的邮件可能是另外一个条件需要检测的一部分,如果标记它为只读,下一次分析邮件时就会漏掉这条,而这条又恰恰是另一个条件触发的组成部分,这样条件2就不会触发了。 另外,还有一个问题想请教下: 我现在是每隔10秒向POP3服务器请求接收邮件,我如果换成5秒钟是不是对POP3服务器造成太大负担? 系统内如果有多个定时器分别处理不同的事件,而且又涉及到频繁的数据库资料查询,如何更好的提升程序的性能?谢谢!
名人堂再聚首 2012-12-27
  • 打赏
  • 举报
回复
谢谢各位的回复,我稍微有了些思路,如果是用定时器肯定会有检测不准确的情况(我试过了使用定时器),我现在在考虑使用一楼兄弟介绍的方法来试试看,邮件是有时间的,如果有问题再向各位请教!
Assassin_ 2012-12-27
  • 打赏
  • 举报
回复
1楼说的时间戳 应该可以试试。
bdmh 2012-12-27
  • 打赏
  • 举报
回复
我想你还是从定时这块考虑吧,一个19秒时,一个21秒时,你非得赶到20秒时查询,那肯定丢掉了
铜臂阿铁木 2012-12-27
  • 打赏
  • 举报
回复
对时间戳进行排序处理 接收到邮件后,检查上一封邮件的发出人和发出时间就可以了。
铜臂阿铁木 2012-12-27
  • 打赏
  • 举报
回复
邮件自身肯定有时间戳
铜臂阿铁木 2012-12-27
  • 打赏
  • 举报
回复
引用 7 楼 sunzongbao2007 的回复:
不要去直接的查过去三十秒。 而是这样: 你不是有数据库么, 检查过的邮件加标记,每次都检查新增的邮件。 比如: 第一个周期你接收到了 A B C D四封邮件, 检查第一个周期,这样标记ABC为已经检查。 D作为下一周期的开头。 第二个周期收到E, 检查E和D的时间间隔, 将D标记为已读,E作为下一周期的开头……循环下去。
这段早就写了……忘了点提交回复………………………………最近脑子进屎了
铜臂阿铁木 2012-12-27
  • 打赏
  • 举报
回复
不要去直接的查过去三十秒。 而是这样: 你不是有数据库么, 检查过的邮件加标记,每次都检查新增的邮件。 比如: 第一个周期你接收到了 A B C D四封邮件, 检查第一个周期,这样标记ABC为已经检查。 D作为下一周期的开头。 第二个周期收到E, 检查E和D的时间间隔, 将D标记为已读,E作为下一周期的开头……循环下去。
zhuawang 2012-12-27
  • 打赏
  • 举报
回复
为什么不把定时器改成多线程来做

110,552

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧