Como (repetidamente) ler no .NET SslStream com um tempo limite?

Eu só preciso ler atéN bytes de umSslStream mas se nenhum byte tiver sido recebido antes de um tempo limite, cancele, deixando o fluxo em um estado válido para tentar novamente mais tarde. (*)

Isso pode ser feito facilmente para fluxos não SSL, ou seja,NetworkStream simplesmente usando seuReadTimeout propriedade que fará o fluxo lançar uma exceção no tempo limite. Infelizmente, essa abordagem não funcionaSslStream de acordo com os documentos oficiais:

SslStream supõe que um tempo limite, juntamente com qualquer outra IOException quando um é lançado do fluxo interno, será tratado como fatal pelo chamador. Reutilizar uma instância SslStream após um tempo limite retornará lixo. Um aplicativo deve fechar o SslStream e lançar uma exceção nesses casos.

[Atualizado 1] Eu tentei uma abordagem diferente como esta:

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

Mas isso não funciona seWait() devolvidafalse: ao ligarReadAsync() novamente mais tarde, lança uma exceção:

Exceção lançada: 'System.NotSupportedException' no System.dll Tests.exe Aviso: 0: Falha na leitura do soquete: System.NotSupportedException: O método BeginRead não pode ser chamado quando outra operação de leitura está pendente.

[Atualização 2] Tentei ainda outra abordagem para implementar tempos limite chamandoPoll(timeout, ...READ) no subjacenteTcpClient socket: se retornartrue, Em seguida, ligueRead() noSSlStreamou se retornarfalse então temos um tempo limite. Isso também não funciona: porqueSslStream presumivelmente usa seus próprios buffers intermediários internos,Poll() pode retornarfalse mesmo se houver dados a serem lidos noSslStream.

[Atualização 3] Outra possibilidade seria escrever um formulário personalizadoStream subclasse que ficaria entreNetworkStream eSslStream e capture a exceção de tempo limite e retorne 0 bytes paraSslStream. Não tenho certeza de como fazer isso e, mais importante, não tenho idéia se retornar uma leitura de 0 bytes paraSslStream ainda não iria corrompê-lo de alguma forma.

(*) A razão pela qual estou tentando fazer isso é que ler de forma síncrona com um tempo limite de um soquete não seguro ou seguro é o padrão que já estou usando no iOS, OS X, Linux e Android para obter código de plataforma cruzada . Como funciona para soquetes não seguros no .NET, o único caso restante éSslStream.

questionAnswers(2)

yourAnswerToTheQuestion