寻求一个解决思路

ffsquare 2016-07-14 03:00:24
我要监听硬件上传的数据,通过回调函数来获取数据,比如电脑A管理4个设备,如果有数据,4个设备会同时上传数据,同时上传时间差不会多于100毫秒,同时上传的数据我通过比对只要1个,如果有设备损坏的情况,只会同时上传2、3个数据,我如何来高效的来识别单次上传的数据?
我目前用Timer来定时检测接收缓存,但是感觉这种做法并不好。希望大家集思广益帮我想一个好一些的办法。
...全文
325 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
ffsquare 2016-07-20
  • 打赏
  • 举报
回复
根据sp1234的启发,稍微修改了程序,改为单独开Thread来判断等待了,以去掉Timer巡检。
token不能为空 2016-07-15
  • 打赏
  • 举报
回复
如果你考虑那种没有收到4台设备消息,而只收到三台的情况下,强行按时间间隔处理的话 好像必须用到timer
wanghui0380 2016-07-14
  • 打赏
  • 举报
回复
如果没有批次滴,那就和地铁一样。地铁没有批次,到点就出发,谁先挤上谁就上(当然你这里4个通道,每次放行1个,哪个通道没人那就没人,地铁不等你,到点就发车)
wanghui0380 2016-07-14
  • 打赏
  • 举报
回复
这个过程其实和火车没啥区别, 乘客凭票上车(票据上显示他就是这个批次的车,就如同你协议上一样),然后火车准点出发,过时不候
wanghui0380 2016-07-14
  • 打赏
  • 举报
回复
一般是用协议和超时 所谓协议,一般这种类型的需求都有一个批次,按你的要求1个批次最多4个 那么协议头上就应该有批次标识,同时我怎么知道设备损坏,这个简单处理可以做超时处理,比如超时100毫秒我认为他掉线了 当然正常的逻辑上掉线/不掉线是另外的心跳包(非长连接的也有服务器主动定时ping客户的做法) 有关批次,如果没有协议保证,我只能认为他的逻辑是,在系统规定超时时间内,这多台机器发送给我第一条数,我把这多台机器的数据zip一个包在推出去,那么这个的逻辑图示意,参考下文的JoinBlock模块处理(当然这样做,在处理上就是各自负责各自的数据流,超时推一个null,然后joinblock收到全体4个整体打包推给下个处理环节) http://www.cnblogs.com/haoxinyue/archive/2013/03/01/2938959.html
runerback 2016-07-14
  • 打赏
  • 举报
回复
执行结果(用随机数模拟设备坏掉的情况):

调用:


执行结果:
runerback 2016-07-14
  • 打赏
  • 举报
回复
具体是这样:





runerback 2016-07-14
  • 打赏
  • 举报
回复
我自己写了个模仿你说的流程的控制台小程序,无奈代码写的太多,上传csdn貌似要很久,所以在想要不要贴代码上来。

具体思路其实就是超过100毫秒之后就立即进行分析数据的步骤然后清除缓存。
ffsquare 2016-07-14
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
你可以把这个作为一个基本的判断原则:定时轮询,通常是懒人想出来的对付领导检查的策略。任何高效率的算法,都是及时处理的,不是轮询的。 除非天然就有轮询需求(例如每个月查一次水表)。如果天然的需求实时,而你写的代码是定时轮询,就不要再争论技术问题了,那一定是懒惰的结果。
我也觉得这样做不好,但是一时半会有想不到其他的方法,所以才上来问一下,麻烦您帮我参考参考。谢谢了
ffsquare 2016-07-14
  • 打赏
  • 举报
回复
引用 11 楼 sp1234 的回复:
你可以把这个作为一个基本的判断原则:定时轮询,通常是懒人想出来的对付领导检查的策略。任何高效率的算法,都是及时处理的,不是轮询的。 除非天然就有轮询需求(例如每个月查一次水表)。如果天然的需求实时,而你写的代码是定时轮询,就不要再争论技术问题了,那一定是懒惰的结果。
假如4台设备都有上传数据,接收到第一个我判断是否可用,可用的话我就直接用了,舍去其他3个数据,如果第一个数据无效,则去判断第二个是否可用,如果全部都不可用,则拿去相对准确一些的数据使用。 如果4台设备其中有一个未触发回调函数,则我只收到3条数据,如何让程序去停止等待接收第4条数据,只处理收到的3条数据。
ffsquare 2016-07-14
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
我写“只取第一个”其实也只是举例。 比如说一共有4个设备注册好了,那么你就在这里判断是不是4个设备都有数据了。假设说有一个设备检测出有故障了,那么你就在这个检测室是不是3个设备都有数据了。假设说只要有50%的设备有数据就可以了,那么你就在这里判断是不是接收到的数据份数少于50%(则只记录)、刚好到达50%的设备传完数据(则处理)、超过50%的设备有数据(则抛弃)........ 总之这是算法流程。这里“做”什么,那是抽象的,要结合你的业务逻辑反复修改。(而且其核心依据,主要来自于业务,而不是来自于技术)
主要是我并不知道该设备是否已经故障,我怎么去协调一段时间内上传的数据的个数?
  • 打赏
  • 举报
回复
你可以把这个作为一个基本的判断原则:定时轮询,通常是懒人想出来的对付领导检查的策略。任何高效率的算法,都是及时处理的,不是轮询的。 除非天然就有轮询需求(例如每个月查一次水表)。如果天然的需求实时,而你写的代码是定时轮询,就不要再争论技术问题了,那一定是懒惰的结果。
  • 打赏
  • 举报
回复
引用 8 楼 ffsquare 的回复:
不是说第一条就一定是有用的数据,有可能第二条、第三条才是有用的数据,每次上传的数据我都需要做分析。 而且数据处理要尽量保证实时,我不能等到下次设备上传数据再来判断上一次数据所有设备都已经上传。所有我这面需要用Timer来尽量保持数据处理的实时性。
我上面说来说去,就是说你的这个结论“需要用Timer来尽量保持数据处理的实时性”,其实怎么看都不合理。怎么看,你都能实时做出判断,而不是定时轮询!
  • 打赏
  • 举报
回复
我写“只取第一个”其实也只是举例。 比如说一共有4个设备注册好了,那么你就在这里判断是不是4个设备都有数据了。假设说有一个设备检测出有故障了,那么你就在这个检测室是不是3个设备都有数据了。假设说只要有50%的设备有数据就可以了,那么你就在这里判断是不是接收到的数据份数少于50%(则只记录)、刚好到达50%的设备传完数据(则处理)、超过50%的设备有数据(则抛弃)........ 总之这是算法流程。这里“做”什么,那是抽象的,要结合你的业务逻辑反复修改。(而且其核心依据,主要来自于业务,而不是来自于技术)
ffsquare 2016-07-14
  • 打赏
  • 举报
回复
引用 5 楼 sp1234 的回复:
也就是说,没有抢到第一位的消息,直接return,什么都不做就很好了。 这也用不着 timer 啊。timer 这个思想在算法上怎么看都是多余的啊。
不是说第一条就一定是有用的数据,有可能第二条、第三条才是有用的数据,每次上传的数据我都需要做分析。 而且数据处理要尽量保证实时,我不能等到下次设备上传数据再来判断上一次数据所有设备都已经上传。所有我这面需要用Timer来尽量保持数据处理的实时性。
  • 打赏
  • 举报
回复
如果是“比对”,那么你的流程设计可能就会更复杂一点。要具体结合你的业务来反复修改。 我只是从大原则上先来考虑如何把关的问题。如论如何,这都谈不上time。无论如何,都应该设计出实时处理的流程!
  • 打赏
  • 举报
回复
当然上面只是举例,实际上 his 可以设计更好的数据结构,你还可以用 session 来命名。这个命名好于 his。 你还应该定时清理过期的 session,例如插入 session 集合之后超过5秒钟的 session 就可以定期清理了。
  • 打赏
  • 举报
回复
引用 2 楼 ffsquare 的回复:
是异步的回调,现在就是想办法来确认数据都已经接受,如果4个设备掉线1个,这样单次只能收到3条数据,我这面程序不能每次都按收到4条数据来处理。
嗯,“用Timer来定时检测接收缓存”是这个意思啊。 那么你在“异步处理消息”之前先检测一下“有没有已经处理过”不就行了吗? 举个例子(仅仅是举例),假设最近处理过的消息都放在
 List<abc> his = new List<abc>();
中,那么你在处理消息之前应该

    lock (his)
    {
        if (判断his中已经包含了要处理的消息)
            return;

        his.Add(new abc());
    }
    进行消息处理;    
也就是说,没有抢到第一位的消息,直接return,什么都不做就很好了。 这也用不着 timer 啊。timer 这个思想在算法上怎么看都是多余的啊。
ffsquare 2016-07-14
  • 打赏
  • 举报
回复
设备发送的数据都是完整的数据,每个设备发送1份,有些可能是无效数据,也有一些是错误的数据,如果都是无效的数据我也会从中拿去一条来储存。 现在程序的逻辑是收到数据我存到缓存里,如果收到全部设备上传的数据就清理缓存,但是如果没有收全的话,Timer来检测,最后一次上传时间超过一秒就直接从已上传的数据中拿一条数据来储存。
  • 打赏
  • 举报
回复
你一会儿说“回调函数来获取数据”,一会儿说“用Timer来定时检测接收缓存”,这个可能就是逻辑流程问题。 当回调函数接收到数据时,应该立刻判断是否已经收到一条完整的消息(也就是你的后边那个操作的第一部分工作)。如果收到了消息,那么就从“接受缓存”中移除整个消息,然后在子线程中处理这条消息内容(立刻释放 I/O 线程,这样不会阻塞随后的接收操作。同时使用系统线程池的工作线程来处理此消息)。 接收缓存中剩下的是取走了一条消息之后的字节。 你的 Timer 是多余的。它原本应该拆分两个操作,一部分在“回调函数”结束前立即执行,一部分由回调函数(可能)注册到系统线程池的子任务去异步执行。
加载更多回复(2)

111,129

社区成员

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

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

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