/// <summary>
                /// Start the I/O thread.
                /// </summary>
                public void Start()
                {
                    m_IsRunning = true;
                    try {
                        if (m_Buffers == null) m_Buffers = new OverlappedIoState(m_ReadBufferSize, m_WriteBufferSize);

                        // Set the time outs
                        NativeMethods.COMMTIMEOUTS timeouts = new NativeMethods.COMMTIMEOUTS();
                        // We read only the data that is buffered
#if PL2303_WORKAROUNDS
                        // Timeout if data hasn't arrived in 10ms, or if the read takes longer than 100ms in total
                        timeouts.ReadIntervalTimeout = 10;
                        timeouts.ReadTotalTimeoutConstant = 100;
                        timeouts.ReadTotalTimeoutMultiplier = 0;
#else
                        // Non-asynchronous behaviour
                        timeouts.ReadIntervalTimeout = -1;
                        timeouts.ReadTotalTimeoutConstant = 0;
                        timeouts.ReadTotalTimeoutMultiplier = 0;
#endif
                        // We have no time outs when writing
                        timeouts.WriteTotalTimeoutMultiplier = 0;
                        timeouts.WriteTotalTimeoutConstant = 500;

                        bool result = UnsafeNativeMethods.SetCommTimeouts(m_ComPortHandle, ref timeouts);
                        if (!result) throw new IOException("Couldn't set CommTimeouts", Marshal.GetLastWin32Error());

                        m_Thread = new Thread(new ThreadStart(OverlappedIoThread));
                        m_Thread.Name = "SerialPortStream_" + Name;
                        m_Thread.IsBackground = true;
                        m_Thread.Start();
                    } catch {
                        m_IsRunning = false;
                        throw;
                    }
                }
                /// <summary>
                /// Dispose resources for this object.
                /// </summary>
                /// <param name="disposing"><b>true</b> if we're disposing from the program, <b>false</b> if
                /// disposing from the finaliser.</param>
                private void Dispose(bool disposing)
                {
                    if (disposing) {
                        if (IsRunning) Stop();
                        if (m_Buffers != null) m_Buffers.Dispose();
                        m_Buffers = null;

                        m_StopRunning.Dispose();
                        m_SerialCommEvent.Dispose();
                        m_ReadEvent.Dispose();
                        m_WriteEvent.Dispose();
                        m_ReadBufferNotFullEvent.Dispose();
                        m_WriteBufferNotEmptyEvent.Dispose();
                        m_ReadBufferNotEmptyEvent.Dispose();
                        m_WriteBufferNotFullEvent.Dispose();
                        m_ReadBufferEvent.Dispose();
                        m_TxBufferEmpty.Dispose();
                        m_WriteClearEvent.Dispose();
                        m_WriteClearDoneEvent.Dispose();
                    }
                }