public void NewReading(SensorReading reading)
 {
     _pending++;
     labelPendingUpload.Text = string.Format("{0} readings waiting to be uploaded", _pending);
     string text = reading.Watts.ToString("#,0");
     if (reading.Sensor == 0)
     {
         labelOverall.Text = text;
     }
     else
     {
         _readings[reading.Sensor] = text;
         listViewAppliances.Items.Clear();
         foreach (var key in _readings.Keys)
         {
             listViewAppliances.Items.Add(new ListViewItem(new string[] { key.ToString(), _readings[key] }));
         }
     }
 }
        private void SerialReader()
        {
            DateTime epochStart = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            while (true)
            {
                try
                {
                    using (SerialPort port = new SerialPort())
                    {
                        port.PortName = _comPort;
                        port.BaudRate = _baudRate;
                        port.DtrEnable = true;
                        port.ReadTimeout = 5000;
                        port.Open();
                        while (true)
                        {
                            try
                            {
                                if (_exit)
                                {
                                    return;
                                }
                                string line = port.ReadLine();
                                //Debug.WriteLine(line);
                                XDocument doc = XDocument.Parse(line, LoadOptions.None);
                                var msg = doc.Element("msg");
                                if (msg != null)
                                {
                                    SensorReading reading = new SensorReading();
                                    var ch1 = msg.Element("ch1");
                                    if (ch1 != null)
                                    {
                                        reading.Timestamp = (int)(DateTime.UtcNow - epochStart).TotalSeconds;
                                        reading.Sensor = int.Parse(msg.Element("sensor").Value);
                                        reading.Watts = int.Parse(ch1.Element("watts").Value);
                                        var ch2 = msg.Element("ch2");
                                        if (ch2 != null)
                                        {
                                            reading.Watts += int.Parse(ch2.Element("watts").Value);
                                        }
                                        var ch3 = msg.Element("ch3");
                                        if (ch3 != null)
                                        {
                                            reading.Watts += int.Parse(ch3.Element("watts").Value);
                                        }
                                        readings.Enqueue(reading);
                                        Debug.WriteLine("time={0}, sensor={1}, watts={2}", reading.Timestamp, reading.Sensor, reading.Watts);

                                        _statusForm.Invoke(new NewReadingHandler(_statusForm.NewReading), reading);
                                    }
                                }
                            }
                            catch (TimeoutException timeout)
                            {
                                //absorb timeouts and try again
                            }
                        }

                    }
                }
                catch
                {
                    //absorb and never die, but at least pause
                    Thread.Sleep(3000);
                }
            }
        }