title: Read SSL via PipeReader in .NET
body: <p>Currently I have a working implementation by using an SSL Stream, wrapped in a bufferedstream, and just calling read/write on the stream using byte arrays.</p>
  
  <p>I want to make this faster, and from some reading it looks like <code>System.IO.Pipelines</code> are the way to go for high performance IO.</p>
  
  <p>A lot of articles/demos I've read only demonstrate code using a socket directly - Which doesn't seem to work with me since I'm using SSL.</p>
  
  <p>I've found some extensions to get a pipereader/writer from a stream > <code>Stream.UsePipeReader()</code> or <code>Stream.UsePipeWriter()</code> so I've tried calling
  <code>SSLStream.UsePipeReader()</code></p>
  
  <p>However I consistently get the error: </p>
  
  <pre><code>System.NotSupportedException :  The ReadAsync method cannot be called when another read operation is pending.
     at System.Net.Security.SslStreamInternal.ReadAsyncInternal[TReadAdapter](TReadAdapter adapter, Memory`1 buffer)
     at Nerdbank.Streams.PipeExtensions.&lt;&gt;c__DisplayClass5_0.&lt;&lt;UsePipeReader&gt;b__1&gt;d.MoveNext() in D:\a\1\s\src\Nerdbank.Streams\PipeExtensions.cs:line 92
  --- End of stack trace from previous location where exception was thrown ---
     at System.IO.Pipelines.PipeCompletion.ThrowLatchedException()
     at System.IO.Pipelines.Pipe.GetReadResult(ReadResult&amp; result)
     at System.IO.Pipelines.Pipe.GetReadAsyncResult()
  </code></pre>
  
  <p>My code to read from the pipe is:</p>
  
  <pre><code>private async Task&lt;string&gt; ReadAsync(PipeReader reader)
          {
  
              var stringBuilder = new StringBuilder();
  
              while (true)
              {
                  var result = await reader.ReadAsync();
  
                  var buffer = result.Buffer;
                  SequencePosition? position;
  
                  do
                  {
                      // Look for a EOL in the buffer
                      position = buffer.PositionOf((byte) '\n');
  
                      if (position != null)
                      {
                          // Process the line
                          ProcessLine(buffer.Slice(0, position.Value), stringBuilder);
                          buffer = buffer.Slice(buffer.GetPosition(1, position.Value));
                      }
                  } while (position != null);
  
                  reader.AdvanceTo(buffer.Start, buffer.End);
  
                  if (result.IsCompleted)
                  {
                      reader.Complete();
                      break;
                  }
              }
  
              return stringBuilder.ToString();
          }
  </code></pre>
  
  <p>It is not being called by any other threads as I've tested it with a lock around it. And I'm only doing a single call at a time for testing purposes.</p>
  
  <p>Can anyone tell me what I'm doing wrong?</p>
  
  <p>Thanks!</p>