自动化控制之重码校验

看到公司项目里每次都写生产流程都是需要一个环节,那就是重码校验。和同事交流有怀疑Queue的性能的,主要是担心队列元素过多效率低。需求:实现一个先进先出FIFO的队列,在每次生产前去本地数据库看看之前生产的批次有没有采集过,如果有则需要读取到队列里。生产中校验某个码,如果校验不重复则加入队列。校验通不过则需要剔除。目前产线的采集器(工业相机)是随产品在流水线各个工位依次触发的。暂时不存在多个线程并发访问FIFO队列的情况,所以即使使用普通的Queue也是正常不出问题的。现在封装了一下,用上了线程安全版本的ConcurrentQueue。

/// <summary>
    /// 重码校验队列
    /// </summary>
    public class RepeatCheckQueue
    {
        protected ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
        private volatile int barcodeCount = 100;
        /// <summary>
        /// 队列长度,默认100
        /// </summary>
        public int BarcodeCount
        {
            get
            {
                return queue.Count;
            }
        }
        /// <summary>
        /// 构造函数,需要传值指明队列长度
        /// </summary>
        /// <param name="count">队列长度</param>
        public RepeatCheckQueue(int count)
        {
            barcodeCount = count;
            //加载已有码的委托声明
            LoadItemFromDB = (list) =>
            {
                if (list.Count > barcodeCount)
                    throw new Exception("队列长度超限!");
                foreach (Barcode code in list)
                    queue.Enqueue(code.Code);
            };
            //校验重码的委托声明
            CheckIsRepeat = (t, isAddtoQueue) =>
            {
                bool result = false;
                result = queue.Contains(t);
                //不存在且需要加入则自动加入队列
                if (!result && isAddtoQueue)
                {
                    queue.Enqueue(t);
                    if (queue.Count > barcodeCount)
                    {
                        string code;
                        queue.TryDequeue(out code);
                    }
                }
                return result;
            };
        }
        /// <summary>
        /// 从数据库加载已有数据
        /// </summary>
        public Action<List<Barcode>> LoadItemFromDB;
        /// <summary>
        /// 检查条码是否重复,并确定是否加入队列
        /// </summary>
        public Func<string, bool, bool> CheckIsRepeat;

        public string GetQueueCode()
        {
            return queue.FirstOrDefault().ToString();
        }
    }

测试用例:

 Stopwatch sw = new Stopwatch();
            List<Barcode> list = new List<Barcode>();
            Func<RepeatCheckQueue> initQueue = () =>
            {
                sw.Start();
                list = LoadFromXML<Barcode>("100w_guid.xml");
                Console.WriteLine(DateTime.Now +"->"+string.Format("{0}个码已经加载到内存!", list.Count));
                var repeatCheckQueue = new RepeatCheckQueue(list.Count);
                repeatCheckQueue.LoadItemFromDB(list);
                return repeatCheckQueue;
            };
            initQueue.BeginInvoke((result) =>
            {
                RepeatCheckQueue checker = initQueue.EndInvoke(result);
                sw.Stop();
                Console.WriteLine(DateTime.Now + "->" + string.Format("{0}个码已经加载到队列!", checker.BarcodeCount));
                Console.WriteLine(DateTime.Now + "->" + string.Format("准备队列耗时:{0} !", sw.ElapsedMilliseconds.ToString()));
                //生成一个测试的随机码
                string check_first = string.Join("", Guid.NewGuid().ToByteArray());
                var result_Check = checker.CheckIsRepeat(check_first, true);
                Console.WriteLine(DateTime.Now + "->" + string.Format("校验的第一个码:{0},", check_first) + result_Check);
                Console.WriteLine(result_Check);
                Console.WriteLine(checker.BarcodeCount);
                Console.WriteLine(DateTime.Now + "->" + string.Format("当前队列的第一个码:{0},", checker.GetQueueCode()) + result_Check);
                Console.WriteLine("******************************");
                //第二个码
                string code_first = list.Skip(0).Take(1).FirstOrDefault().Code;
                result_Check = checker.CheckIsRepeat(code_first, true);
                Console.WriteLine(string.Format(DateTime.Now + "->" + "文件里第2码:{0},", code_first) + result_Check);
                //第三个
                string code_second = list.Skip(2).Take(1).FirstOrDefault().Code;
                result_Check = checker.CheckIsRepeat(code_second, true);
                Console.WriteLine(string.Format(DateTime.Now + "->" + "文件里第3码:{0},", code_second) + result_Check);
                Console.WriteLine(checker.BarcodeCount);
                Console.WriteLine("************并行测试************");
                Random rd = new Random();
                //随机取队列里的一个码来校验
                Action action = () =>
                {
                    for (int i = 0; i < 3; i++)
                    {
                        int index = rd.Next(list.Count);
                        string code = list.Skip(index).Take(1).FirstOrDefault().Code;
                        result_Check = checker.CheckIsRepeat(code, true);
                        Console.WriteLine(DateTime.Now + "->" + code + "," + result_Check);
                        Console.WriteLine(checker.BarcodeCount);
                    }
                };
                Parallel.Invoke(action, action, action, action, action, action, action, action);
            }, null);
            Console.WriteLine("正在初始化重码队列...");
            Console.ReadKey();

测试结果:队列里放入100万个码,使用从xml读取100万,然后一个入队的方式,耗时3秒不到,ConcurrentQueue的好处就是支持多线程分批次和并行入队出队。不需要lock,没毛病,一个字:快。

时间: 2024-07-30 13:21:20

自动化控制之重码校验的相关文章

利用BeEF REST API自动化控制僵尸主机

本文已发布于Freebuf,属于原创奖励计划,未经许可禁止转载. http://www.freebuf.com/articles/network/137662.html 一. 前言 关于BeEF,不再多介绍,它的强大毋庸置疑,利用它我们可以做很多事情.最近的一些实验,需要用beef批量自动进行控制,发现网上也没有过多关于这方面内容的介绍,于是学习了一下它的API,顺便练习一下python编程,这里把自己的学习内容分享下.本文涉及的一些内容可能具有一定的攻击性,请遵守国家法律,禁止用于非法用途.

利用BeEF REST API自动化控制僵尸主机 --转载--作者ssooking

一. 前言 关于BeEF,不再多介绍,它的强大毋庸置疑,利用它我们可以做很多事 情.最近的一些实验,需要用beef进行批量自动控制,发现网上也没有过多关于这方面内容的介绍,于是学习了一下它的API,顺便练习一下python编 程,这里把自己的学习内容分享下.本文涉及的一些内容可能具有一定的攻击性,请遵守国家法律,禁止用于非法用途. 二. 通过API控制beef BeEF从0.4.3.3,版本开始,提供了静态API接口,用户可以通过发送HTTP / JSON请求控制Beef. 我们可以通过程序,批

005-优化web请求一-gzip压缩、http缓存控制和缓存校验[Pragma、Expires、Cache-Control、max-age、Last-Modified、用户刷新访问、避免过度304]

优化Web应用的典型技术:缓存控制头信息.Gzip.应用缓存.ETag.反应型技术[异步方法调用和WebSocket] 一.模板缓存 spring.thymeleaf.cache=true spring.messages.cache-duration= 二.Gzip压缩 Gzip是一种能够被浏览器直接理解的压缩算法.服务器会提供压缩响应,会耗一些cpu,但是减少带宽 GZIP压缩是一个经常被用到的WEB性能优化的技巧,它主要是对页面代码,CSS,Javascript,PHP等文件进行压缩,而且在

自动化控制之线程池的使用

昨天反编译看了公司项目首席架构师实现的线程池.非常之惊讶,在没有.net 4可用的年代.那思想和那技术是相当的可以啊.佩服. 这里说的线程池是一个类我总觉得这样叫有点不名副其实.其实就是一个类内部实现了FIFO队列,把临时数据放到这个队列里,“线程池类”内容按照入队的先后次序触发一个负责解析校验等的事件,并且把数据传递个这个事件. 好了,上代码: /// <summary> /// 自定义线程池类,不依赖.net Queue实现了先进先出处理队列里数据 /// </summary>

expect 自动化控制命令

expect 的核心是 spawn expect send set spawn 调用要执行的命令expect 等待命令提示信息的出现,也就是捕捉用户输入的提示:send 发送需要交互的值,替代了用户手动输入内容set 设置变量值interact 执行完成后保持交互状态,把控制权交给控制台,这个时候就可以手工操作了.如果没有这一句登录完成后会退出,而不是留在远程终端上.expect eof 这个一定要加,与 spawn 对应表示捕获终端输出信息终止,类似于 if....endif expect 脚

互联网+助力恒德智能装备远程自动化控制

产品的智能化,又为服务的网络化奠定了基础.以前是用户发现机器坏了打客服电话报修,企业再派维修人员到现场服务.现在国机重工的工程机械产品大都装了传感器,油温.油压等重要数据可实时显示.一旦超过正常范围,就会通过互联网自动报警,售后服务人员用手机就可以远程查看产品性能. 对设备使用情况的实时监控,将一些故障隐患消除在萌芽状态,有效提高了产品稳定性,很受用户欢迎.也许日后我们就不需要客服呼叫中心了,工程师可能比用户更早察觉设备故障,用户还没来得及报修,我们的售后服务人员就已经到场了. 互联网促进了装备

通过存储过程提单时进行数据校验,优先于预算控制

19.42版支持 通过存储过程提单时进行数据校验,优先于预算控制,如果数据校验不通过将不再执行预算控制 实现方法,在XML里添加节,同时支持多种校验拼接:    <DataControls>      <!--如果返回不为空则显示返回同时不允许提交,通过 G_FORM_ID 获得当前单据id -->     <DataContol name="金额控制举例1">           exec Logining 'root','','',''     

springMVC学习(7)-springMVC校验

一.校验理解: 对于安全要求较高点建议在服务端进行校验. 控制层conroller:校验页面请求的参数的合法性.在服务端控制层conroller校验,不区分客户端类型(浏览器.手机客户端.远程调用) 业务层service(使用较多):主要校验关键业务参数,仅限于service接口中使用的参数. 持久层dao:一般是不校验 二.SpringMVC校验需求: springmvc使用hibernate的校验框架validation(和hibernate没有任何关系). 思路: 页面提交请求的参数,请求

MonkeyServer的使用及自动化

●MonkeyServer机制简介 Monkey可以在设备上启动一个服务端让客户机远程的连接到设备,对设备进行调试和控制 ●MonkeyServer使用 ?启动MonkeyServer adb shell monkey --port 1080 & ?连接MonkeyServer adb forward tcp:1080 tcp:1080 //把PC机的端口映射到设备暴露出来的端口上 telnet 127.0.0.1 1080 //通过telnet本机连接到MonkeyServer ●Monkey