How to correctly read zipped data from NetworkStream with BeginRead/EndRead?

372 Views Asked by At

Here is the AsyncCallback that I'm using to read data from GZipStream created on top of NetworkStream:

    void ReadCompressedDataCallback(IAsyncResult ar)
    {
        var state = ar.AsyncState as ReadCompressedDataState;
        try
        {
            switch (state.State)
            {
                case EReadCompressedDataState.BeginRead:
                    state.State = EReadCompressedDataState.EndRead;
                    state.InputStream.BeginRead(state.Buf, 0, state.Buf.Length, ReadCompressedDataCallback, state);
                    break;
                case EReadCompressedDataState.EndRead:
                    var read = state.InputStream.EndRead(ar);
                    if (read==0)
                    {
                        state.OnCompleted();
                        return;
                    }
                    state.Result.Write(state.Buf,0,read);
                    state.State = EReadCompressedDataState.BeginRead;
                    ReadCompressedDataCallback(ar);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
        catch (Exception e)
        {
            state.LastException = e;
            state.OnCompleted();
        }
    }

state.InputStream is something like new GZipStream(NetworkStream).

My problem is that first time I call read = state.InputStream.EndRead(ar);, read is always 0, and the reading stops. When, in the debugger, I start reading again, some data is read.

According to documentation I've read, NetworkStream returns 0 bytes on reading only when there are no more bytes to read, yet here 0 bytes is returned and than some data follows on the next read.

How do I correctly read all gzipped data without risking "deadlocking" the app into waiting for data that never arrives?

1

There are 1 best solutions below

0
On

Your sample code looks a bit unusual. I think another answer might help you Calling BeginRead from a NetworkStream