如何检测NetworkStream何时完成Rx查询

时间:2015-05-18 22:04:22

标签: c# .net system.reactive tcpclient networkstream

我使用Rx从NetworkStream中读取并将结果作为Hot Observable提供。 即使查询工作得很好,我也不确定基于NetworkStream完成序列的条件是否最合适。我有序列完成的情况,另一侧的TcpListener没有完成或关闭连接。

这是查询。我将很高兴得到一些关于安全终止序列的正确条件的建议:

private IDisposable GetStreamSubscription(TcpClient client)
{
    return Observable.Defer(() => {
      var buffer = new byte[client.ReceiveBufferSize];

      return Observable.FromAsync<int>(() => {
         return client.GetStream ().ReadAsync (buffer, 0, buffer.Length);
      })
      .SubscribeOn(NewThreadScheduler.Default)
      .Select(x => buffer.Take(x).ToArray());
    })
    .Repeat()
    .TakeWhile(bytes => bytes.Any()) //This is the condition to review
    .Subscribe(bytes => {
        //OnNext Logic
    }, ex => {
        //OnError logic
    }, () => {
        //OnCompleted Logic
    });
}

为了清楚我的问题,我需要知道检测网络流何时在另一端完成的最佳方法(因为断开连接,错误或其他原因)。现在我通过调用ReadAsync来做到这一点,直到没有返回任何字节,但我不知道这是否完全安全。

1 个答案:

答案 0 :(得分:0)

这样做你想要的吗?

private IDisposable GetStreamSubscription(TcpClient client)
{
    return Observable
        .Defer(() =>
        {
            var buffer = new byte[client.ReceiveBufferSize];
            return Observable.Using(
                () => client.GetStream(),
                st => Observable.While(
                    () => st.DataAvailable,
                    Observable.Start(() =>
                    {
                        var bytes = st.Read(buffer, 0, buffer.Length);
                        return buffer.Take(bytes).ToArray();
                    })));
        })
        .SubscribeOn(NewThreadScheduler.Default)
        .Subscribe(bytes => {
            //OnNext Logic
        }, ex => {
            //OnError logic
        }, () => {
            //OnCompleted Logic
        });
}

请注意,这可以安全地处理流,并在不再有任何可用数据时结束。