带有while(true)循环的线程以某种方式退出

时间:2014-11-12 22:12:21

标签: c# multithreading while-loop

我有一个应该在我的程序中连续运行的线程,并从一组传感器解析传入的串行数据。

//initialized as a global variable
System.Threading.Thread processThread = new System.Threading.Thread(ProcessSerialData);

//this gets called when you press the start button
processThread.Start(); 

private void ProcessSerialData()
{
    while (true)
    {
        //do a whole bunch of parsing stuff
    }
    int howDidYouGetHere = 0;
}

我的程序如何到达“int howDidYouGetHere = 0”行?

完整代码可以在这里找到:

    /// <summary>
    /// ProcessSerialData thread will be used to continue testing the connection to the controller,
    /// process messages in the incoming message queue (actually a linked list), 
    /// and sends new messages for updated data.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void ProcessSerialData()
    {
        while (true)
        {
            UpdateAhTextbox(test.ampHoursOut.ToString());

            if (!relayBoard.OpenConn())
            {
                MessageBox.Show("Connection to controller has been lost.");
                testInterrupted = "Lost connection. Time = " + test.duration;
                UpdateStatusText(false);
                ShutErDown();
            }

            /////////////////////////////////////////////////////
            if (incomingData.Count > 0)
            {
                string dataLine = "";
                try
                {
                    dataLine = incomingData.First();
                    UpdateParsedDataTextbox(dataLine + "\r\n");
                }
                catch (System.InvalidOperationException emai)
                {
                    break; //data hasn't come in yet, it will by the time this runs next.
                }

                incomingData.RemoveFirst();

                if (dataLine.Contains("GET")) // some sensor values (analog/temp/digital) has come in
                {
                    if (dataLine.Contains("GETANALOG")) // an analog value has come in
                    {
                        int index = dataLine.IndexOf("CH");
                        int pin = (int)Char.GetNumericValue(dataLine[index + 2]);

                        double value = 0;
                        int dataLineLength = dataLine.Length;
                        if (dataLineLength > 13) // value is appended to end of line
                        {
                            try
                            {
                                value = Convert.ToDouble(dataLine.Substring(13));
                            }
                            catch // can't convert to double
                            {
                                int index2 = dataLine.IndexOf("CH", 3);
                                if (index2 != -1) // there happen to be two sets of commands stuck together into one
                                {
                                    string secondHalf = dataLine.Substring(index2);
                                    incomingData.AddFirst(secondHalf);
                                }
                            }
                        }
                        else // value is on the next line
                        {
                            try
                            {
                                value = Convert.ToDouble(incomingData.First());
                                incomingData.RemoveFirst();
                            }
                            catch // can't convert to double
                            {
                                MessageBox.Show("Error occured: " + dataLine);
                            }
                        }
                        switch (pin)
                        {
                            case 1:
                                ReadVoltage(value);
                                break;
                            case 2:
                                ReadAmperage(value);
                                break;
                        }
                    }
                    else if (dataLine.Contains("GETTEMP")) // received reply with temperature data
                    {
                        int index = dataLine.IndexOf("CH");
                        int pin = (int)Char.GetNumericValue(dataLine[index + 2]); // using index of CH, retrieve which pin this message is coming from

                        double value = 0;
                        int dataLineLength = dataLine.Length;
                        if (dataLineLength > 11) // value is appended to end of line
                        {
                            try
                            {
                                value = Convert.ToDouble(dataLine.Substring(11));
                            }
                            catch // can't convert to double
                            {
                                int index2 = dataLine.IndexOf("CH", 3);
                                if (index2 != -1) // there happen to be two sets of commands stuck together into one
                                {
                                    string secondHalf = dataLine.Substring(index2);
                                    incomingData.AddFirst(secondHalf);
                                }
                            }
                        }
                        else // value is on the next line
                        {
                            value = Convert.ToDouble(incomingData.First());
                            incomingData.RemoveFirst();
                        }
                        ReadTemperature(pin, value);
                    }
                    else // must be CH3.GET
                    {
                        int index = dataLine.IndexOf("CH");
                        int pin = (int)Char.GetNumericValue(dataLine[index + 2]); // using index of CH, retrieve which pin this message is coming from

                        if (pin == 3) // only care if it's pin 3 (BMS), otherwise it's a mistake
                        {
                            double value = 0;
                            int dataLineLength = dataLine.Length;
                            if (dataLineLength > 7) // value is appended to end of line
                            {
                                try
                                {
                                    value = Convert.ToDouble(dataLine.Substring(7));
                                }
                                catch // can't convert to double
                                {
                                    int index2 = dataLine.IndexOf("CH", 3);
                                    if (index2 != -1) // there happen to be two sets of commands stuck together into one
                                    {
                                        string secondHalf = dataLine.Substring(index2);
                                        incomingData.AddFirst(secondHalf);
                                    }
                                }
                            }
                            else // value is on the next line
                            {
                                value = Convert.ToDouble(incomingData.First());
                                incomingData.RemoveFirst();
                            }
                            ReadBMS(value);
                        }
                    }
                }
                else if (dataLine.Contains("REL")) // received reply about relay turning on or off.
                {
                    if (dataLine.Contains("RELS")) // all relays turning on/off
                    {
                        if (dataLine.Contains("ON"))
                        {
                            for (int pin = 1; pin <= 4; pin++)
                            {
                                test.contactors[pin] = true;
                            }
                        }
                        else // "OFF"
                        {
                            for (int pin = 1; pin <= 4; pin++)
                            {
                                test.contactors[pin] = false;
                            }
                        }
                    }
                    else // single relay is turning on/off
                    {
                        int index = dataLine.IndexOf("REL");
                        int pin = (int)Char.GetNumericValue(dataLine[index + 3]);

                        if (dataLine.Contains("ON"))
                        {
                            test.contactors[pin] = true;
                        }
                        else if (dataLine.Contains("OFF"))
                        {
                            test.contactors[pin] = false;
                        }
                        else if (dataLine.Contains("GET"))
                        {
                            if (Convert.ToInt32(incomingData.First()) == 1)
                                test.contactors[pin] = true;
                            else
                                test.contactors[pin] = false;
                            incomingData.RemoveFirst();
                        }
                    }
                }
            }
            /////////////////////////////////////////////////////

            // we only want more data if we're done processing the current data, otherwise we're stuck with too much and processing is heavily delayed.
            if (isTestRunning && incomingData.Count < 3)
            {
                //read & output v, a, bms state
                sendToController("CH1.GETANALOG"); // get voltage
                sendToController("CH2.GETANALOG"); // get amperage
                sendToController("CH3.GET"); // get BMS state

                //read & output temperature
                sendToController("CH4.GETTEMP"); // get temperature
                sendToController("CH5.GETTEMP");

                string lines = "Ah Out: " + test.ampHoursOut + ", Voltage: " + test.voltage +
                    ", Amperage: " + test.amperage + ", Cell Temperature: " + test.tempBattery +
                    ", Load Temperature: " + test.tempLoad;
                WriteToLog(lines);
            }
        }
        int howDidYouGetHere = 0;
    }

2 个答案:

答案 0 :(得分:2)

break(忽略嵌套switch内的那些)会突破while循环。

答案 1 :(得分:-1)

也许你曾尝试使用UpdateParsedDataTextbox来更新你的UI这会导致InvalidOperationException(然后打破while循环),因为你试图从不拥有它的线程访问UI控件控制。