В настоящее время у меня есть рабочая реализация, использующая поток SSL, обернутая в поток с буферизацией, и просто вызывающая чтение/запись в потоке с использованием байтовых массивов.
Я хочу сделать это быстрее, и из некоторого прочтения похоже, что System.IO.Pipelines
- это путь к высокопроизводительному вводу-выводу.
Многие статьи/демонстрации, которые я только читаю, демонстрируют код, использующий сокет напрямую - который, кажется, не работает со мной, так как я использую SSL.
Я нашел несколько расширений, чтобы получить конвейер/писатель из потока> Stream.UsePipeReader()
или Stream.UsePipeWriter()
, поэтому я попытался вызвать
SSLStream.UsePipeReader()
Однако я постоянно получаю ошибку:
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.<>c__DisplayClass5_0.<<UsePipeReader>b__1>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& result)
at System.IO.Pipelines.Pipe.GetReadAsyncResult()
Мой код для чтения из канала:
private async Task<string> 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();
}
Это не вызывается никакими другими потоками, так как я тестировал его с замком вокруг него. И я делаю только один звонок за один раз для целей тестирования.
Может кто-нибудь сказать мне, что я делаю не так?
Спасибо!