Manipulando desconexões do WinRT StreamSocket (do lado do servidor e do cliente)

Eu tenho um aplicativo que estou escrevendo para o Windows 8 / WinRT que usa a API StreamSocket para fazer uma conexão de streaming para um servidor. Ou seja, o servidor transmite dados para o cliente, às vezes com metatags e pode desconectar a qualquer momento.

O problema que estou tendo é que eu não tenho idéia de como detectar quando o servidor foi desconectado. Não parece haver nenhum evento ou propriedade na classe StreamSocket, seus fluxos de entrada ou saída, ou nas classes DataReader / DataWriter que têm alguma coisa a ver com o status da conexão.

Além disso, o ReadAsync do método DataReader não está falhando depois que o lado do servidor se desconecta do cliente. Em vez disso, a operação é bem-sucedida, e os dados que ela preenche em seu buffer são apenas a última coisa que o servidor enviou para ela (ou seja, não está limpando seu buffer interno, embora eu possa ver que ela "consumiu" o buffer cada vez que eu chamo ReadByte). Ele faz isso para cada chamada subseqüente ao ReadAsync - recarregando o buffer com o que o servidor enviou por último antes de ser desconectado. Aqui está uma versão simplificada do código:

<code>    public async Task TestSocketConnectionAsync()
    {
        var socket = new StreamSocket();
        await socket.ConnectAsync(new HostName(Host), Port.ToString(),
            SocketProtectionLevel.PlainSocket);
        var dr = new DataReader(socket.InputStream);
        dr.InputStreamOptions = InputStreamOptions.Partial;

        this.cts = new CancellationTokenSource();
        this.listenerOperation = StartListeningAsync(dr, cts);
    }

    public async Task StartListeningAsync(DataReader dr, CancellationTokenSource cts)
    {
        var token = cts.Token;
        while (true)
        {
            token.ThrowIfCancellationRequested();
            var readOperation = dr.LoadAsync(1024);
            var result = await readOperation;
            if (result <= 0 || readOperation.Status != Windows.Foundation.AsyncStatus.Completed)
            {
                cts.Cancel(); // never gets called, status is always Completed, result always > 0
            }
            else
            {
                while (dr.UnconsumedBufferLength > 0)
                {
                    byte nextByte = dr.ReadByte();

                    // DriveStateMachine(nextByte);
                }
            }
        }
    }
</code>

questionAnswers(1)

yourAnswerToTheQuestion