Как (неоднократно) читать из .NET SslStream с таймаутом?

Мне просто нужно прочитать доN байты изSslStream но если байт не был получен до истечения времени ожидания, отмените его, оставив поток в допустимом состоянии, чтобы повторить попытку позже. (*)

Это может быть легко сделано для потоков без SSL, т.е.NetworkStream просто используя егоReadTimeout свойство, которое заставит поток вызвать исключение по таймауту. К сожалению, этот подход не работает наSslStream согласно официальным документам:

SslStream предполагает, что таймаут вместе с любым другим IOException, когда он выбрасывается из внутреннего потока, будет вызываться вызывающим как фатальный. Повторное использование экземпляра SslStream после истечения времени ожидания вернет мусор. Приложение должно закрыть SslStream и выдать исключение в этих случаях.

[Обновлено 1] Я попробовал другой подход, как это:

task = stream->ReadAsync(buffer, 0, buffer->Length);
if (task->Wait(timeout_ms)) {
   count = task->Result;
   ...
}

Но это не работает, еслиWait() возвращенныйfalse: при звонкеReadAsync() позже снова выдает исключение:

Возникло исключение: «System.NotSupportedException» в System.dll Tests.exe Предупреждение: 0: сбой чтения из сокета: System.NotSupportedException: метод BeginRead не может быть вызван, когда другая операция чтения ожидает выполнения.

[Обновление 2] Я попробовал еще один подход для реализации таймаутов, позвонивPoll(timeout, ...READ) на основеTcpClient сокет: если он возвращаетtrueзатем позвонитеRead() наSSlStreamили если он вернетсяfalse тогда у нас есть тайм-аут. Это тоже не работает: потому чтоSslStream предположительно использует свои собственные внутренние промежуточные буферы,Poll() может вернутьсяfalse даже если есть данные для чтения вSslStream.

[Обновление 3] Другой возможностью было бы написать кастомStream подкласс, который будет сидеть междуNetworkStream а такжеSslStream и захватить исключение тайм-аута и вернуть 0 байтов вместоSslStream, Я не уверен, как это сделать, и что более важно, я понятия не имею, возвращаю ли 0 байтов, прочитанныхSslStream все равно не испортишь это как-то.

(*) Причина, по которой я пытаюсь это сделать, заключается в том, что синхронное чтение с тайм-аутом из незащищенного или безопасного сокета - это шаблон, который я уже использую в iOS, OS X, Linux и Android для некоторого кроссплатформенного кода. , Это работает для небезопасных сокетов в .NET, поэтому единственный оставшийся случайSslStream.

Ответы на вопрос(2)

Ваш ответ на вопрос