private async void RxThreadProc() { try { if (IsConnected) { #if !WindowsCE m_stream.ReadTimeout = DefaultTimeout; #endif } } catch (ObjectDisposedException) { IsConnected = false; } m_rxCancelToken.Token.ThrowIfCancellationRequested(); // start a ping timer on a period less than the above timeout (else we'll timeout and exit) m_pingTimer = new Timer(PingTimerProc, null, PingPeriod, PingPeriod); List <byte> header = new List <byte>(4); while ((ConnectionState == ConnectionState.Connecting) || (ConnectionState == ConnectionState.Connected)) { if (m_rxCancelToken.Token.IsCancellationRequested) { m_rxCancelToken.Token.ThrowIfCancellationRequested(); } header.Clear(); // the first byte gives us the type try { var byte0 = m_stream.ReadByte(); if (byte0 == -1) { await Task.Delay(500); continue; } //var messageType = (MessageType)(byte0 >> 4); header.Add((byte)byte0); byte lengthByte; // now pull the "remaining length" do { lengthByte = (byte)m_stream.ReadByte(); header.Add(lengthByte); } while ((lengthByte & 0x80) != 0); var length = FixedHeader.DecodeRemainingLength(header, 1); byte[] buffer = null; int read = 0; if (length > 0) { // and pull the payload buffer = new byte[length]; do { read += m_stream.Read(buffer, read, length - read); } while (read < length); } // deserialize and dispatch DeserializeAndDispatchMessage(header.ToArray(), buffer); } catch (Exception ex) { // happens during hang up, maybe on error // needs testing if (TracingEnabled) { Output.WriteLine("!!! Exception in MQTTBroker.RxProc\r\n" + ex.Message); } //if (Debugger.IsAttached) Debugger.Break(); IsConnected = false; } } m_pingTimer.Dispose(); }