写程序遇到一个逻辑问题,欢迎大家来讨论。100分相送

时间:2020-12-22 21:27:19
我的需求是这样的:
有一个生产线,该生产线上的每一个产品都被两台仪器(a和b)同时检测,两台仪器(a和b)分别检测产品的不同部位.

在我的程序中有一个Form,分别为两台仪器(a和b)实例化了一个对象(即共两个Form对象),用于单独监视两台仪器(a和b).

两台仪器(a和b)每检查一个产品,都会各自触发事件A,并且在A中我们能获取到所检查的产品是否合格(两台仪器独立检测,即同一个

产品a仪器触发A事件并报不合格,b仪器触发A事件可能报合格。它们检测不同方面,它们只关心自己检测的部分是否合格)。

如果同一产品两台仪器都报不合格,那么不合格数加一;如果只有一台仪器报不合格,那么不合格数也加一。

注意:两台仪器有可能只有一台工作。

问:如何计算检测产品的总数和不合格数?

帮顶,有分!

46 个解决方案

#1


你这不是逻辑问题...建议你好好学一下OOP...

Form只是呈现...逻辑处理要先设计好...检测数据要存储...有了存储的数据你想计算什么都可以...

#2


你说的我都明白.

请别光说不练,能拿出结果才是好猫.

总的检测数很容易获取到,不合格产品数考虑到延迟等问题不那么好计算.

检测频率大概为1秒钟7个产品

#3


把数量变量和是否合格的判断变量设为静态变量试试。

#4


那你的产品有没有类似序列号的标识?

#5


关键问题在于如何判断分别触发的A事件是否检测的就是同一产品.

#6


仪器的检测号能获取到,但如果两台仪器不同时开,那它们的检测号也不一样

#7


不知道你们的不合格标准到底是什么
如果说任一不合格就是不合格的话,那么就完全没有必要出现两台仪器检测不合格的问题,那么做就是在浪费工序。
任一工序不合格则为不合格,数量+1,最后只需要吧两个检测器检测出的不合格数相加就好了。

#8


看来只能用笨方法,程序来记录两台仪器的检测数量了

#9


检测的产品型号也设成静态的不就结了。

#10


怎么用程序记录就成笨方法呢,难道人工去数啊

#11


不是"每一个产品都被两台仪器(a和b)同时检测"么?

#12


TO:smaworm 

任一不合格也不能这么办啊.

像你那样计算,如果同时检测5个产品,两台仪器分别都认为全部不合格,一加岂不是10了?

#13


TO:hli33 

机器是同时检测,在一秒7产品的速度下,难以保证触发事件也是同时吧?

#14


按你的需求,不要试图从时间延迟这点来判断是否是同一个产品。

而是对a、b机器检测的产品分别独立的判断是否合格,最后进行一个汇总。

这里问题的关键是4L说的“你的产品是否存在序列号并且可以让机器检测出来”。

因为这是能够汇总的前提。

#15


TO:Efcndi 
很有道理!

#16


继续等待,看有没有更好的答案!

#17


1. 这个问题关键是看如何判断产品合格不合格的逻辑上
2. 合格不合格的逻辑最主要的问题是一台机器怎么知道另一台机器的状态,及工作和不工作- 

根据以上两点,我们应该提供一种方法让另一台机器知道当前机器的状态。

3. 当每台机器检测产品后把结果写入产品的结果列表中,然后去掉用一个产品生成最终结果函数,这个函数知道那台机器在工作根据机器给他的信息。

3.1 当它看到所有当前工作的机器都象它提交了检测后,就去检查结果列表,如果发现不合格就给出最终的不合格,否则返回合格。
3.2 当它看到当前工作的机器还没有全部提交检测,它返回一个未完成的状态。


有点说不清楚,用伪代码说明可能更好,不过懒得写了。

#18


原来你的这两个检测仪器是绑定在一起的啊,我本来以为是分来的两个。
如果是分开的话,假设检测100个产品,两台分别检测50个
a检测出2个不合格
b检测出3个不合格
那么不合格的肯定要剔除掉啊,不用再重复检测了。
也就是a只要再检测47个
b只要检测48个就好了

#19


1.被检测的产品必须包含两个检测的结果a和b,另有一个是否已被检测的标识flag
2.将被检测的产品放入一个ArrayList中
3.获取ArrayList中flag为true的数量,和所有a&&b的结果即可得出你要的数据

#20


检测的时候给每个产品加个标志符,试试可以不

#21


知道仪器的开机时间、结束时间就可以知道A、B仪器是不是在检测同个产品

#22


接14楼
两个ArrayList ar1,ar2
a机器检测的结果存ar1合格存1合格存0
ar1{1,1,1,0,0,0}
b机器检测的结果存ar2合格存1合格存0
ar2{1,1,1,0,1,1}

数组的index对应你产品
a.b分别检测该产品的不用部位
如果ar1[0]*ar1[0]=1那么产品0合格
如果ar1[4]*ar1[4]=0那么产品4不合格

#23


修正:
a机器检测的结果存ar1合格存1不合格存0 
ar1{1,1,1,0,0,0} 
b机器检测的结果存ar2合格存1不合格存0 
ar2{1,1,1,0,1,1} 

#24


你真的都明白?你的需求和逻辑都不清楚怎么给你结果?

如果同一产品两台仪器都报不合格,那么不合格数加一;如果只有一台仪器报不合格,那么不合格数也加一。

注意:两台仪器有可能只有一台工作。 
---------------------------
不工作的算什么?不合格?

例:

产品P;
仪器A检测的项:A1,A2,A3;
仪器B检测的项:B1,B2,B3;

你关心仪器A还是仪器B?错了,要关心的是P...

这样P至少有七个属性:ID,A1,A2,A3,B1,B2,B3;

1.用两个线程从A和B取检测数据,不要去管什么事件,只管把数据存起来...
2.用第三个线程读取数据,合不合格有多少合格只是统计分析的事罢了...

#25


问题越来越明朗了

#26


TO:CMIC

能否说的再明白些,刚刚你说的我没能理解清楚,谢谢!

#27


一个产品有两个检查项. a 和b 
每个检查项可能有三个状态之一 合格/不合格/未定义
一个产品检查列表可能是
产品  状态a 状态b
1     true   null
2     false  false
3     null   true

....................
至于怎么查不合格的总数要看逻辑了.
一般的来说只要有一个状态为不合格,我们则一般可以认定此产品不合格
.不管用什么方式存储的上述状态列表,应该都很容易找到你要的答案了

#28


产品    设备         状态
1      a          合格
1      b          不合格
2      b          合格 


#29


#30


想到另一个方法:用一个HashTable,型号作键(如果有的话,没有就当我没发过这些贴子),状态作值。剩下的不用我多说了吧。

#31


两台仪器分别为两个对象,两个对象中分别一个属性列表,可以使用HashTable,即本仪器监视的index已经是否合格
还有需要一个属性,就是本仪器开始的时候,另外一个仪器所监视的index。
这样的话只要对比本仪器和另外一个仪器的相应index,已经是否合格就可以了,当然先开的仪器不是从第一个开始计算了,是从后开的那个仪器的记录的index开始计算。

#32



Machine machine
{
//记录检测的index,以及相应的产品是否合格
HashTable ht;
//记录本机开始的时候,先开的机器在监测的第几个产品。为0的时候说明本仪器先开。
int index;
}
后面 后开的从1开始计算,先开的从index开始计算,同时计算产品是否合格。

#33


如果这事在日常生活中你知道怎么去处理,那现在应该问题不大。

业务逻辑清楚了,分析好了,无非是用编程语言把你的逻辑表达出来。(我往往认为是跟用普通话来表达出业务逻辑差不了多少。)

#34


我觉得用时间确定同一产品不准确 有时候两台机会有时间误差 除非能在两台机都成功的情况下让产品进入合格的箱子 不合格的放入另一个箱子 然后再让下一个产品过来 或者是贴上产品扫描码 各自检测然后写入数据库 测试完再得出结果

#35


关注

#36


一直关注,顶一个

#37


顶一下,学习中

#38


//========================产品合格类==========================
class Product
{

private bool bool passproduct=false;//该产品是否合格
public bool GetProduct{get{return this.product;}}
private bool passA=false;//a仪器检测是否合格
private bool passB=false;//b仪器检测是否合格
public Product(bool a,bool b)//构造函数
{
this.passA=a;
this.passB=b;
if(this.passA==true&&this.passB==true)
{
this.product=true;
}
else
{
this.product=false;
}
}
//===========================以下是主程序========================
class Main
{
private static int passCount=0;
private static int allCount=0;

public static void Main()
{
bool pass=true;
while(pass)
{
Product p=new Product(仪器a检测报告,仪器b检测报告)
if(p.passproduct==true)
{
allCount+=1;
passCount+=1;
}
else
{
allCount+=1;
}
pass=Convert.ToBool(Console.ReadLine());//是否需要判断下一个产品
}


Console.WriteLine("一共检验了{0}件产品,其中合格的有{1}件",allCount.ToString(),passCount.ToString());
//
}

#39


都是牛人,最好和客户沟通,看他们实际是怎么计算的

#40


既然是同时,用二维数组怎么样?
{{0,0}
 {0,1}
 {1,0}
 {1,1}}
sum=0;sum++;

#41


检测完毕写在表里面.想怎么操作都行!!!

#42


支持CMIC!

#43


一个线程用两个Queue<Bool>()分别记录A、B设备的检测结果,一个线程统计结果,同时给Queue减肥。

#44


这是我43楼的例程,主线程计数,子线程启动设备检测。
using System;
using System.Collections.Generic;
using System.Threading;

namespace ConsoleApplication74
{
    class Instrument
    {
        public static int Count;
        private string name;
        private int number;

        public Instrument(string name)
        {
            this.name = name;
            this.number = 0;
            this.results = new Queue<bool>();
        }

        private Queue<bool> results;
        public Queue<bool> Results
        {
            get { return results; }
        }

        public void Detect()
        {
            while (number++ < Instrument.Count)
            {
                Thread.Sleep(new Random().Next(500));
                bool result = (new Random().Next(2) == 0);
                Console.WriteLine("设备{0}检测到第{1}个产品{2}", name, number, result ? "合格" : "不合格");
                results.Enqueue(result);
            }
        }

        public static int BadCounter(params Instrument[] instruments)
        {
            int number = 0;
            int badCount = 0;
            while (number++ < Instrument.Count)
            {
                bool result = true;
                foreach (Instrument i in instruments)
                {
                    while (i.results.Count == 0)
                    {
                        Thread.Sleep(100);
                    }
                }
                foreach (Instrument i in instruments)
                {
                    result &= i.results.Dequeue();
                }
                if (!result)
                    badCount++;
            }
            return badCount;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Instrument.Count = 10;
            Instrument a = new Instrument("A");
            Instrument b = new Instrument("B");
            new Thread(a.Detect).Start();
            new Thread(b.Detect).Start();
            int badCount = Instrument.BadCounter(a, b);
            Console.WriteLine("检测到不合格产品{0}个", badCount);
            Console.ReadKey();
        }
    }
}

#45


using System;
using System.Collections.Generic;
using System.Threading;

namespace ConsoleApplication74
{
    class Instrument
    {
        // 待检测产品的数量
        public static int Count;
        
        // 检测仪器的动态对象的名字
        private string name;

        // 检测仪器的动态对象检测产品的个数
        private int number;

        // 检测仪器的动态对象检测出的结果的缓存队列
        private Queue<bool> results;
        public Queue<bool> Results
        {
            get { return results; }
        }
        
        public Instrument(string name)
        {
            this.name = name;
            this.number = 0;
            this.results = new Queue<bool>();
        }

        // 检测仪器的动态对象的检测方法
        // 用随机数模拟检测时的时延和检测结果
        public void Detect()
        {
            // 检测完所有产品后
            // 检测仪器的动态对象的检测方法才结束
            while (number++ < Instrument.Count)
            {
                // 模拟时延,造成两个检测仪器有时检测两个产品的情况
                Thread.Sleep(new Random().Next(500));

                // 模拟结果,随机数是 0 就代表检测结果合格
                bool result = (new Random().Next(2) == 0);
                Console.WriteLine("设备{0}检测到第{1}个产品{2}", name, number, result ? "合格" : "不合格");
                
                // 结果加入缓存队列
                results.Enqueue(result);
            }
        }

        // 此静态方法用于计数,在该类中定义只为归类好看,定义在别的类里也行
        public static int BadCounter(params Instrument[] instruments)
        {
            // 记录统计了多少个产品的结果
            int number = 0;
            
            // 记录不合格产品的数量
            int badCount = 0;

            // 统计完所有产品的结果后才结束循环,返回结果
            while (number++ < Instrument.Count)
            {
                // 因为要统计不合格的 (false)
                // 所以先假设当前产品是合格的 (true)
                // 只要有发现任何一个检测结果不合格,该变量就会变为 false
                bool result = true;

                // 检测当前产品所有检测是否都已有结果
                foreach (Instrument i in instruments)
                {
                    // 如果当前读取的缓存里没有结果,就等100毫秒,再读一下看看
                    while (i.results.Count == 0)
                    {
                        Thread.Sleep(100);
                    }
                }

                // 把当前产品的所有检测结果从缓存里剔除
                // 并与 result 进行 & 计算
                // 所有结果都为 true ,该产品才能合格
                foreach (Instrument i in instruments)
                {
                    result &= i.results.Dequeue();
                }

                // 如果不合格,计数
                if (!result)
                    badCount++;
            }
            
            // 返回不合格的产品数量
            return badCount;
        }
    }


    class Program
    {
        // 问题1:流水线长时间检测,用表保存全部结果可能会溢出
        // 问题2:流水线上的产品不一定有序列号,就是有,让检测仪器读取也会很麻烦
        // 方案 :用 Queue 队列缓存各仪器的检测结果,计数程序随时计数并释放内存,控制缓存的大小
        //        同时让所有检测仪器按顺序检测,并保存结果,保证顺序就不需要序列号了。

        static void Main(string[] args)
        {
            // 初始化待检测产品的数量,假设是10个
            // 此静态变量是检测方法和计数方法的结束条件
            Instrument.Count = 10;

            // 实例化两个检测仪器
            Instrument a = new Instrument("A");
            Instrument b = new Instrument("B");
            
            // 启动仪器的检测程序,依次检测产品
            // 检测结果会保存进 results 里
            // results 是每个仪器对象自身的 Queue<bool> 队列
            new Thread(a.Detect).Start();
            new Thread(b.Detect).Start();

            // 启动计数程序
            // 同一产品的各个检测结果在计数后就没有用了,所以一齐清理掉,释放内存
            // 这样长时间检测也没问题
            int badCount = Instrument.BadCounter(a, b);
            Console.WriteLine("检测到不合格产品{0}个", badCount);
            Console.ReadKey();
        }
    }
}


加上注释,省得看着累眼

#46


先顶,回家看

#1


你这不是逻辑问题...建议你好好学一下OOP...

Form只是呈现...逻辑处理要先设计好...检测数据要存储...有了存储的数据你想计算什么都可以...

#2


你说的我都明白.

请别光说不练,能拿出结果才是好猫.

总的检测数很容易获取到,不合格产品数考虑到延迟等问题不那么好计算.

检测频率大概为1秒钟7个产品

#3


把数量变量和是否合格的判断变量设为静态变量试试。

#4


那你的产品有没有类似序列号的标识?

#5


关键问题在于如何判断分别触发的A事件是否检测的就是同一产品.

#6


仪器的检测号能获取到,但如果两台仪器不同时开,那它们的检测号也不一样

#7


不知道你们的不合格标准到底是什么
如果说任一不合格就是不合格的话,那么就完全没有必要出现两台仪器检测不合格的问题,那么做就是在浪费工序。
任一工序不合格则为不合格,数量+1,最后只需要吧两个检测器检测出的不合格数相加就好了。

#8


看来只能用笨方法,程序来记录两台仪器的检测数量了

#9


检测的产品型号也设成静态的不就结了。

#10


怎么用程序记录就成笨方法呢,难道人工去数啊

#11


不是"每一个产品都被两台仪器(a和b)同时检测"么?

#12


TO:smaworm 

任一不合格也不能这么办啊.

像你那样计算,如果同时检测5个产品,两台仪器分别都认为全部不合格,一加岂不是10了?

#13


TO:hli33 

机器是同时检测,在一秒7产品的速度下,难以保证触发事件也是同时吧?

#14


按你的需求,不要试图从时间延迟这点来判断是否是同一个产品。

而是对a、b机器检测的产品分别独立的判断是否合格,最后进行一个汇总。

这里问题的关键是4L说的“你的产品是否存在序列号并且可以让机器检测出来”。

因为这是能够汇总的前提。

#15


TO:Efcndi 
很有道理!

#16


继续等待,看有没有更好的答案!

#17


1. 这个问题关键是看如何判断产品合格不合格的逻辑上
2. 合格不合格的逻辑最主要的问题是一台机器怎么知道另一台机器的状态,及工作和不工作- 

根据以上两点,我们应该提供一种方法让另一台机器知道当前机器的状态。

3. 当每台机器检测产品后把结果写入产品的结果列表中,然后去掉用一个产品生成最终结果函数,这个函数知道那台机器在工作根据机器给他的信息。

3.1 当它看到所有当前工作的机器都象它提交了检测后,就去检查结果列表,如果发现不合格就给出最终的不合格,否则返回合格。
3.2 当它看到当前工作的机器还没有全部提交检测,它返回一个未完成的状态。


有点说不清楚,用伪代码说明可能更好,不过懒得写了。

#18


原来你的这两个检测仪器是绑定在一起的啊,我本来以为是分来的两个。
如果是分开的话,假设检测100个产品,两台分别检测50个
a检测出2个不合格
b检测出3个不合格
那么不合格的肯定要剔除掉啊,不用再重复检测了。
也就是a只要再检测47个
b只要检测48个就好了

#19


1.被检测的产品必须包含两个检测的结果a和b,另有一个是否已被检测的标识flag
2.将被检测的产品放入一个ArrayList中
3.获取ArrayList中flag为true的数量,和所有a&&b的结果即可得出你要的数据

#20


检测的时候给每个产品加个标志符,试试可以不

#21


知道仪器的开机时间、结束时间就可以知道A、B仪器是不是在检测同个产品

#22


接14楼
两个ArrayList ar1,ar2
a机器检测的结果存ar1合格存1合格存0
ar1{1,1,1,0,0,0}
b机器检测的结果存ar2合格存1合格存0
ar2{1,1,1,0,1,1}

数组的index对应你产品
a.b分别检测该产品的不用部位
如果ar1[0]*ar1[0]=1那么产品0合格
如果ar1[4]*ar1[4]=0那么产品4不合格

#23


修正:
a机器检测的结果存ar1合格存1不合格存0 
ar1{1,1,1,0,0,0} 
b机器检测的结果存ar2合格存1不合格存0 
ar2{1,1,1,0,1,1} 

#24


你真的都明白?你的需求和逻辑都不清楚怎么给你结果?

如果同一产品两台仪器都报不合格,那么不合格数加一;如果只有一台仪器报不合格,那么不合格数也加一。

注意:两台仪器有可能只有一台工作。 
---------------------------
不工作的算什么?不合格?

例:

产品P;
仪器A检测的项:A1,A2,A3;
仪器B检测的项:B1,B2,B3;

你关心仪器A还是仪器B?错了,要关心的是P...

这样P至少有七个属性:ID,A1,A2,A3,B1,B2,B3;

1.用两个线程从A和B取检测数据,不要去管什么事件,只管把数据存起来...
2.用第三个线程读取数据,合不合格有多少合格只是统计分析的事罢了...

#25


问题越来越明朗了

#26


TO:CMIC

能否说的再明白些,刚刚你说的我没能理解清楚,谢谢!

#27


一个产品有两个检查项. a 和b 
每个检查项可能有三个状态之一 合格/不合格/未定义
一个产品检查列表可能是
产品  状态a 状态b
1     true   null
2     false  false
3     null   true

....................
至于怎么查不合格的总数要看逻辑了.
一般的来说只要有一个状态为不合格,我们则一般可以认定此产品不合格
.不管用什么方式存储的上述状态列表,应该都很容易找到你要的答案了

#28


产品    设备         状态
1      a          合格
1      b          不合格
2      b          合格 


#29


#30


想到另一个方法:用一个HashTable,型号作键(如果有的话,没有就当我没发过这些贴子),状态作值。剩下的不用我多说了吧。

#31


两台仪器分别为两个对象,两个对象中分别一个属性列表,可以使用HashTable,即本仪器监视的index已经是否合格
还有需要一个属性,就是本仪器开始的时候,另外一个仪器所监视的index。
这样的话只要对比本仪器和另外一个仪器的相应index,已经是否合格就可以了,当然先开的仪器不是从第一个开始计算了,是从后开的那个仪器的记录的index开始计算。

#32



Machine machine
{
//记录检测的index,以及相应的产品是否合格
HashTable ht;
//记录本机开始的时候,先开的机器在监测的第几个产品。为0的时候说明本仪器先开。
int index;
}
后面 后开的从1开始计算,先开的从index开始计算,同时计算产品是否合格。

#33


如果这事在日常生活中你知道怎么去处理,那现在应该问题不大。

业务逻辑清楚了,分析好了,无非是用编程语言把你的逻辑表达出来。(我往往认为是跟用普通话来表达出业务逻辑差不了多少。)

#34


我觉得用时间确定同一产品不准确 有时候两台机会有时间误差 除非能在两台机都成功的情况下让产品进入合格的箱子 不合格的放入另一个箱子 然后再让下一个产品过来 或者是贴上产品扫描码 各自检测然后写入数据库 测试完再得出结果

#35


关注

#36


一直关注,顶一个

#37


顶一下,学习中

#38


//========================产品合格类==========================
class Product
{

private bool bool passproduct=false;//该产品是否合格
public bool GetProduct{get{return this.product;}}
private bool passA=false;//a仪器检测是否合格
private bool passB=false;//b仪器检测是否合格
public Product(bool a,bool b)//构造函数
{
this.passA=a;
this.passB=b;
if(this.passA==true&&this.passB==true)
{
this.product=true;
}
else
{
this.product=false;
}
}
//===========================以下是主程序========================
class Main
{
private static int passCount=0;
private static int allCount=0;

public static void Main()
{
bool pass=true;
while(pass)
{
Product p=new Product(仪器a检测报告,仪器b检测报告)
if(p.passproduct==true)
{
allCount+=1;
passCount+=1;
}
else
{
allCount+=1;
}
pass=Convert.ToBool(Console.ReadLine());//是否需要判断下一个产品
}


Console.WriteLine("一共检验了{0}件产品,其中合格的有{1}件",allCount.ToString(),passCount.ToString());
//
}

#39


都是牛人,最好和客户沟通,看他们实际是怎么计算的

#40


既然是同时,用二维数组怎么样?
{{0,0}
 {0,1}
 {1,0}
 {1,1}}
sum=0;sum++;

#41


检测完毕写在表里面.想怎么操作都行!!!

#42


支持CMIC!

#43


一个线程用两个Queue<Bool>()分别记录A、B设备的检测结果,一个线程统计结果,同时给Queue减肥。

#44


这是我43楼的例程,主线程计数,子线程启动设备检测。
using System;
using System.Collections.Generic;
using System.Threading;

namespace ConsoleApplication74
{
    class Instrument
    {
        public static int Count;
        private string name;
        private int number;

        public Instrument(string name)
        {
            this.name = name;
            this.number = 0;
            this.results = new Queue<bool>();
        }

        private Queue<bool> results;
        public Queue<bool> Results
        {
            get { return results; }
        }

        public void Detect()
        {
            while (number++ < Instrument.Count)
            {
                Thread.Sleep(new Random().Next(500));
                bool result = (new Random().Next(2) == 0);
                Console.WriteLine("设备{0}检测到第{1}个产品{2}", name, number, result ? "合格" : "不合格");
                results.Enqueue(result);
            }
        }

        public static int BadCounter(params Instrument[] instruments)
        {
            int number = 0;
            int badCount = 0;
            while (number++ < Instrument.Count)
            {
                bool result = true;
                foreach (Instrument i in instruments)
                {
                    while (i.results.Count == 0)
                    {
                        Thread.Sleep(100);
                    }
                }
                foreach (Instrument i in instruments)
                {
                    result &= i.results.Dequeue();
                }
                if (!result)
                    badCount++;
            }
            return badCount;
        }
    }


    class Program
    {
        static void Main(string[] args)
        {
            Instrument.Count = 10;
            Instrument a = new Instrument("A");
            Instrument b = new Instrument("B");
            new Thread(a.Detect).Start();
            new Thread(b.Detect).Start();
            int badCount = Instrument.BadCounter(a, b);
            Console.WriteLine("检测到不合格产品{0}个", badCount);
            Console.ReadKey();
        }
    }
}

#45


using System;
using System.Collections.Generic;
using System.Threading;

namespace ConsoleApplication74
{
    class Instrument
    {
        // 待检测产品的数量
        public static int Count;
        
        // 检测仪器的动态对象的名字
        private string name;

        // 检测仪器的动态对象检测产品的个数
        private int number;

        // 检测仪器的动态对象检测出的结果的缓存队列
        private Queue<bool> results;
        public Queue<bool> Results
        {
            get { return results; }
        }
        
        public Instrument(string name)
        {
            this.name = name;
            this.number = 0;
            this.results = new Queue<bool>();
        }

        // 检测仪器的动态对象的检测方法
        // 用随机数模拟检测时的时延和检测结果
        public void Detect()
        {
            // 检测完所有产品后
            // 检测仪器的动态对象的检测方法才结束
            while (number++ < Instrument.Count)
            {
                // 模拟时延,造成两个检测仪器有时检测两个产品的情况
                Thread.Sleep(new Random().Next(500));

                // 模拟结果,随机数是 0 就代表检测结果合格
                bool result = (new Random().Next(2) == 0);
                Console.WriteLine("设备{0}检测到第{1}个产品{2}", name, number, result ? "合格" : "不合格");
                
                // 结果加入缓存队列
                results.Enqueue(result);
            }
        }

        // 此静态方法用于计数,在该类中定义只为归类好看,定义在别的类里也行
        public static int BadCounter(params Instrument[] instruments)
        {
            // 记录统计了多少个产品的结果
            int number = 0;
            
            // 记录不合格产品的数量
            int badCount = 0;

            // 统计完所有产品的结果后才结束循环,返回结果
            while (number++ < Instrument.Count)
            {
                // 因为要统计不合格的 (false)
                // 所以先假设当前产品是合格的 (true)
                // 只要有发现任何一个检测结果不合格,该变量就会变为 false
                bool result = true;

                // 检测当前产品所有检测是否都已有结果
                foreach (Instrument i in instruments)
                {
                    // 如果当前读取的缓存里没有结果,就等100毫秒,再读一下看看
                    while (i.results.Count == 0)
                    {
                        Thread.Sleep(100);
                    }
                }

                // 把当前产品的所有检测结果从缓存里剔除
                // 并与 result 进行 & 计算
                // 所有结果都为 true ,该产品才能合格
                foreach (Instrument i in instruments)
                {
                    result &= i.results.Dequeue();
                }

                // 如果不合格,计数
                if (!result)
                    badCount++;
            }
            
            // 返回不合格的产品数量
            return badCount;
        }
    }


    class Program
    {
        // 问题1:流水线长时间检测,用表保存全部结果可能会溢出
        // 问题2:流水线上的产品不一定有序列号,就是有,让检测仪器读取也会很麻烦
        // 方案 :用 Queue 队列缓存各仪器的检测结果,计数程序随时计数并释放内存,控制缓存的大小
        //        同时让所有检测仪器按顺序检测,并保存结果,保证顺序就不需要序列号了。

        static void Main(string[] args)
        {
            // 初始化待检测产品的数量,假设是10个
            // 此静态变量是检测方法和计数方法的结束条件
            Instrument.Count = 10;

            // 实例化两个检测仪器
            Instrument a = new Instrument("A");
            Instrument b = new Instrument("B");
            
            // 启动仪器的检测程序,依次检测产品
            // 检测结果会保存进 results 里
            // results 是每个仪器对象自身的 Queue<bool> 队列
            new Thread(a.Detect).Start();
            new Thread(b.Detect).Start();

            // 启动计数程序
            // 同一产品的各个检测结果在计数后就没有用了,所以一齐清理掉,释放内存
            // 这样长时间检测也没问题
            int badCount = Instrument.BadCounter(a, b);
            Console.WriteLine("检测到不合格产品{0}个", badCount);
            Console.ReadKey();
        }
    }
}


加上注释,省得看着累眼

#46


先顶,回家看