public void ReadFromPrinter()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            timeSinceLastReadAnything.Restart();
            // we want this while loop to be as fast as possible. Don't allow any significant work to happen in here
            while (CommunicationState == CommunicationStates.AttemptingToConnect
                || (PrinterIsConnected && serialPort.IsOpen && !Disconnecting))
            {
                try
                {
                    while (serialPort.BytesToRead > 0)
                    {
                        char nextChar = (char)serialPort.ReadChar();
                        using (TimedLock.Lock(this, "ReadNextChar"))
                        {
                            if (nextChar == '\r' || nextChar == '\n')
                            {
                                lastLineRead = lineBeingRead;
                                lineBeingRead = "";

                                // process this command
                                {
                                    StringEventArgs currentEvent = new StringEventArgs(lastLineRead);
                                    CommunicationUnconditionalFromPrinter.CallEvents(this, currentEvent);

                                    FoundStringEventArgs foundResponse = new FoundStringEventArgs(currentEvent.Data);
                                    ReadLineStartCallBacks.CheckForKeys(foundResponse);
                                    ReadLineContainsCallBacks.CheckForKeys(foundResponse);

                                    if (foundResponse.SendToDelegateFunctions)
                                    {
                                        ReadLine.CallEvents(this, currentEvent);
                                    }
                                }

                                if (CommunicationState == CommunicationStates.AttemptingToConnect)
                                {
                                    CommunicationState = CommunicationStates.Connected;
                                }
                            }
                            else
                            {
                                lineBeingRead += nextChar;
                            }
                            timeSinceLastReadAnything.Restart();
                        }
                    }

                    Thread.Sleep(1);
                }
                catch (TimeoutException)
                {
                }
                catch (IOException)
                {
                    OnConnectionFailed(null);
                }
                catch (InvalidOperationException)
                {
                    // this happens when the serial port closes after we check and before we read it.
                }
                catch (UnauthorizedAccessException)
                {
                    OnConnectionFailed(null);
                }
            }
        }
        void WriteToPrinter(string lineToWrite, string lineWithoutChecksum)
        {
            if (PrinterIsConnected || CommunicationState == CommunicationStates.AttemptingToConnect)
            {
                if (serialPort != null && serialPort.IsOpen)
                {
                    // write data to communication
                    {
                        StringEventArgs currentEvent = new StringEventArgs(lineToWrite);
                        CommunicationUnconditionalToPrinter.CallEvents(this, currentEvent);

                        if (lineWithoutChecksum != null)
                        {
                            FoundStringEventArgs foundStringEvent = new FoundStringEventArgs(lineWithoutChecksum);
                            WriteLineStartCallBacks.CheckForKeys(foundStringEvent);
                            WriteLineContainsCallBacks.CheckForKeys(foundStringEvent);

                            if (foundStringEvent.SendToDelegateFunctions)
                            {
                                WroteLine.CallEvents(this, currentEvent);
                            }
                        }
                    }

                    try
                    {
                        timeSinceLastReadAnything.Restart();
                        timeHaveBeenWaitingForOK.Restart();
                        serialPort.Write(lineToWrite);
                    }
                    catch (IOException)
                    {
                        OnConnectionFailed(null);
                    }
                    catch (TimeoutException)
                    {
                    }
                }
                else
                {
                    OnConnectionFailed(null);
                }
            }
        }