【问题标题】:While loop, checking last runWhile循环,检查上次运行
【发布时间】:2013-01-23 22:53:15
【问题描述】:

我的 While 循环有问题,这个 while 循环需要在上次我的 While 循环中发生变化时更新。

这是我的代码,它在一个线程中运行:

private void CheckAllPorts()
{
    while (true)
    {
            MultipleClock = false;
            OneClock = false;
            NoClock = false;

            portCount = 0;

            //clear the string list.
            MultiplePortNames.Clear();

            //create an object searcher and fill it with the path and the query provided above.
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

            try
            {
                foreach (ManagementObject queryObj in searcher.Get())
                {
                    if (queryObj["InstanceName"].ToString().Contains("USB") || queryObj["InstanceName"].ToString().Contains("FTDIBUS"))
                    {
                        portCount = searcher.Get().Count;

                        if (portCount > 1)
                        {
                            MultiplePortNames.Add(queryObj["PortName"].ToString());
                            form1.UpdateListBox(MultiplePortNames);
                            MultipleClock = true;
                        }
                        else if (portCount == 1)
                        {
                            MultiplePortNames.Add(queryObj["PortName"].ToString());
                            form1.UpdateListBox(MultiplePortNames);
                            OneClock = true;
                        }
                    }
                    else
                    {
                        NoClock = true;
                        form1.UpdateListBox(MultiplePortNames);
                    }
                }
            }
            catch
            {
                NoClock = true;
                form1.UpdateListBox(MultiplePortNames);
            }

        Debug.WriteLine("NoClock = " + NoClock);
        Debug.WriteLine("OneClock = " + OneClock);
        Debug.WriteLine("MultipleClock = " + MultipleClock);

        Thread.Sleep(500);
    }
}

所以如果 portCount 上次是 1,而这次是其他值,例如:0 或 4,那么 它需要执行这段代码:

form1.UpdateListBox(MultiplePortNames);

当portCount上次是2,这次也是2时,代码不应该被执行。

有人知道我的问题的解决方案吗?

【问题讨论】:

  • 为什么你的 while 语句中有一个硬编码的“True”?
  • 仅用于调试信息。

标签: c# .net foreach while-loop


【解决方案1】:

除了这段代码的整体结构存在明显问题(你能告诉我你打算什么时候退出那个 while(true) 吗?)并且只关注你的问题,我认为你应该以这种方式改变内部循环

    int lastCount = 0;
    while (true)
    {
            portCount = 0;
            MultipleClock = false;
            OneClock = false;
            NoClock = false;

            //clear the string list.
            MultiplePortNames.Clear();

            //create an object searcher and fill it with the path and the query provided above.
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);

            try
            {
                portCount = searcher.Get().Count;

                foreach (ManagementObject queryObj in searcher.Get())
                {
                    if (queryObj["InstanceName"].ToString().Contains("USB") || queryObj["InstanceName"].ToString().Contains("FTDIBUS"))
                    {

                        if (portCount >= 1)
                            MultiplePortNames.Add(queryObj["PortName"].ToString());
                    }
                }
            }
            catch
            {
                 // Don't like an empty catch, but perhaps in this case it could be justified
            } 
            if(portCount == 1) 
                OneClock = true;
            else if(portCount > 1)
                MultipleClock = true;
            else
                NoClock = true;

            if(lastCount != portCount)
            {
                 lastCount = portCount;
                 form1.UpdateListBox(MultiplePortNames);
            }
            Debug.WriteLine("NoClock = " + NoClock);
            Debug.WriteLine("OneClock = " + OneClock);
            Debug.WriteLine("MultipleClock = " + MultipleClock);

            Thread.Sleep(500);
    }

我添加了一个lastCount 变量来跟踪USB 端口发现代码上的前一个循环的结果,并将内部循环更改为仅在foreach 循环结束时调用列表框更新。不知道 xxxClock 变量是否还在使用。

【讨论】:

  • 它在一个线程中运行,并且这个线程永远不会停止,这个线程会将所有连接的USB设备显示在一个列表框中,所以当一个被拔出时,它会立即可见,
  • foreach 的正文中再次调用 Count() 方法非常糟糕
  • 您应该推荐哪种方式来计算 searcher.Get() 查询的结果数?
  • @YuriyRozhovetskiy:它不一定是高性能的,但它可以工作 - 但是,OP 没有在那里为 IEnumerable<T> 调用 Count() 扩展方法;它看起来像是对Count 的属性访问,所以我假设searcher.Get() 实际上返回了List<T>
  • @YuriyRozhovetskiy,对,我没听懂。可以很容易地确定范围
【解决方案2】:

您需要添加另一个变量来保留上一次检查的值。 然后您可以将当前金额与之前的金额进行比较,并相应地执行您的逻辑。

将该值存储为 try 块中的最后一步。 不过,不要将 int newVar=0 放在 while 块的开头,否则不会得到所需的结果。

您还需要稍微清理一下代码。

编辑:看起来史蒂夫刚刚做到了。 (额外的 var+clean up)

【讨论】:

    【解决方案3】:

    尝试像这样重新排列您的代码:

    private void CheckAllPorts()
    {
        while (true)
        {
            MultipleClock = false;
            OneClock = false;
            NoClock = false;
    
            portCount = 0;
    
            //clear the string list.
            MultiplePortNames.Clear();
    
            //create an object searcher and fill it with the path and the query provided above.
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
    
            try
            {
                var results = searcher.Get().Where(queryObj=>
                        queryObj["InstanceName"].ToString().Contains("USB") || 
                        queryObj["InstanceName"].ToString().Contains("FTDIBUS"));
    
                if (portCount != results.Count())
                {
                    portCount = results.Count();
    
                    if (portCount > 1)
                    {
                        MultipleClock = true;
                    }
                    else if (portCount == 1)
                    {
                        OneClock = true;
                    }
                    else if (portCount == 0)
                    {
                        NoClock = true;
                    }
    
                    foreach (ManagementObject queryObj in results)
                    {
                            MultiplePortNames.Add(queryObj["PortName"].ToString());
                    }
    
                    form1.UpdateListBox(MultiplePortNames);
                }
            }
            catch
            {
                NoClock = true;
                form1.UpdateListBox(MultiplePortNames);
            }
    
            Debug.WriteLine("NoClock = " + NoClock);
            Debug.WriteLine("OneClock = " + OneClock);
            Debug.WriteLine("MultipleClock = " + MultipleClock);
    
            Thread.Sleep(500);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-12-18
      • 2011-11-02
      • 1970-01-01
      • 2020-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多