title: Continuously reading from serial port asynchronously properly
body: <p>I'm just going to preface this by saying I just started trying to use Async today, so I have a very limited understanding of what I am doing. </p>
  
  <p>I was previously using threads to read data from a serial port, process that data into data to write, and then writing it. I had 1 thread reading data and placing it into a buffer, another thread processing data from a buffer, and a final thread writing it. This way if I clicked a button, I could send additional data.</p>
  
  <p>Now I am just trying to learn and ensure I am doing everything properly, so I am trying to read data from the serial port, and add that data to a multilined textbox. Here's the code:</p>
  
  <p>Connect to serial port, if successful, call <code>UpdateMessageBox</code> which is async:</p>
  
  <pre><code>private void serialConnectClick(object sender, EventArgs e)
  {
      if (!_serialConnected)
      {
          _serialConnected = SerialConnect(portCombo.Text, int.Parse(baudCombo.Text));
          if (!_serialConnected)
          {
              portCombo.SelectedIndex = 0;
              messageTextBox.Text += "Failed to connect.\r\n";
              return;
          }
  
          serialConnectBtn.Text = "Disconnect";
          serialStatusLabel.Text = "Serial: Connected";
          serialStatusLabel.ForeColor = Color.Blue;
          messageTextBox.Text += "Connected\r\n";
          VDIportCombo.Enabled = false;
          soundSuccess.Play();
          UpdateMessageBox(); // this is an async function
      }
  }
  </code></pre>
  
  <p>This continuously calls <code>ReadLineAsync</code> and adds the result to the textbox:</p>
  
  <pre><code>public async Task UpdateMessageBox()
  {
      messageTextBox.Text += "Reading data from serial.";
      while (_serialConnected)
      {
          string message = await SerialReadLineAsync(serial);
          messageTextBox.Text += message;
      }
  }
  </code></pre>
  
  <p>And this does <code>ReadAsync</code> on the <code>SerialPort.BaseStream</code>, and only returns data when we get a full line (denoted by a newline character):</p>
  
  <pre><code>async Task&lt;string&gt; SerialReadLineAsync(SerialPort serialPort)
  {
      byte[] buffer = new byte[1];
      string result = string.Empty;
      Debug.WriteLine("Let's start reading.");
  
      while (true)
      {
          await serialPort.BaseStream.ReadAsync(buffer, 0, 1);
          result += serialPort.Encoding.GetString(buffer);
  
          if (result.EndsWith(serialPort.NewLine))
          {
              result = result.Substring(0, result.Length - serialPort.NewLine.Length);
              result.TrimEnd('\r','\n');
              Debug.Write(string.Format("Data: {0}", result));
              result += "\r\n";
              return result;
          }
      }
  }
  </code></pre>
  
  <p>Am I doing everything correctly? Can I call an async method from the UI thread? Visual studios is telling me I <em>should</em> use await, but it is just suggesting that.</p>
  
  <p>I want other code to run on the UI thread while it is continuously reading, so I don't want to <code>await</code> the <code>UpdateMessageBox</code> function. If this were a thread, I would just want the read thread to operate in the background, and I would just do <code>myReadThread.Start()</code>, is there something similar for async?</p>
  
  <p><strong>EDIT:</strong> Just to clarify, this code does work, but I want to know if it's the "proper" way to do what I am doing.</p>