locked
streamSocket.InputStream.AsStreamForRead() vs new DataReader(streamSocket.InputStream)/LoadAsync()

    Question

  • I'm using a StreamSocket in my WP8.1 (xaml) app and when reading data it sometimes returns 0.

    my code looks like this:

    var stream = _streamSocket.InputStream.AsStreamForRead(BufferSize);
    var buffer = new byte[BufferSize];
    while (true)
    {
        var readCount = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
        if (readCount <= 0)
            throw new InvalidOperationException("No data to read in socket stream"); <---- error happens here
            
        // process data and stop when marker in data is reached
    }

    my app sends a request to an http like server then expects to receive a response in the code above.
    my question is: why does this happen ?

    I recently switch from DataReader to standard .Net streams (using AsStreamForRead) and before the switch I wasn't getting this kind of error.

    code before looked like this:

    using (var dataReader = new DataReader(socket.InputStream))
    {
        dataReader.InputStreamOptions = InputStreamOptions.Partial;
        await dataReader.LoadAsync(BufferSize).AsTask().ConfigureAwait(false);
        // read as much as dataReader.UnconsumedBufferLength bytes....    
        dataReader.DetachStream();
    }
    can it happen that Stream.ReadAsync() doesn't wait for data to come in the socket
    while DataReader/LoadAsync() does ?

    Wednesday, March 25, 2015 9:30 PM

Answers

  • Reading zero bytes from an InputStream means that the stream is over.

    If you believe the Stream wrapper over the IInputStream is not working correctly, you could try:

    IInputStream stream = _streamSocket.InputStream;
    byte[] buffer = new byte[BufferSize];
    while (true)
    {
        IBuffer bufferResult = await stream.ReadAsync(
            buffer.AsBuffer(),
            (uint)buffer.Length,
            InputStreamOptions.Partial).AsTask().ConfigureAwait(false);
        buffer = bufferResult.ToArray();
        if (bufferResult.Length <= 0)
        {
            throw new InvalidOperationException("No data to read in socket stream");
        }
    
        // process data and stop when marker in data is reached
    }
    

    Thursday, March 26, 2015 10:32 PM
  • Hi cuneyiit,

    by "stream is over" you mean the streamsocket is closed ?

    -> The stream is over means there is no more data coming and we can treat it as closed.

    is it possible to see the source code of DataReader ? I know it's native code but since you are at microsoft can you perhaps look at what DataReader.LoadAsync() does and how it does it using InputStream ?

    -> Sorry I don't think its possible. It's not open source yet :P

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, April 8, 2015 12:48 AM
    Moderator

All replies

  • Reading zero bytes from an InputStream means that the stream is over.

    If you believe the Stream wrapper over the IInputStream is not working correctly, you could try:

    IInputStream stream = _streamSocket.InputStream;
    byte[] buffer = new byte[BufferSize];
    while (true)
    {
        IBuffer bufferResult = await stream.ReadAsync(
            buffer.AsBuffer(),
            (uint)buffer.Length,
            InputStreamOptions.Partial).AsTask().ConfigureAwait(false);
        buffer = bufferResult.ToArray();
        if (bufferResult.Length <= 0)
        {
            throw new InvalidOperationException("No data to read in socket stream");
        }
    
        // process data and stop when marker in data is reached
    }
    

    Thursday, March 26, 2015 10:32 PM
  • Hi Stankiewicz,

    thanks for your help.

    - by "stream is over" you mean the streamsocket is closed ?

    - I had started implementing the solution you proposed (before your answer) but then I thought it must be done like this in the wrapper returned by AsStreamForRead(). After finding the assembly on my computer, and looking at its source code (with ILSpy) I can see that it is indeed doing something like what your proposed.

    - is it possible to see the source code of DataReader ? I know it's native code but since you are at microsoft can you perhaps look at what DataReader.LoadAsync() does and how it does it using InputStream ?

    thanks

    Friday, March 27, 2015 8:49 AM
  • Hi cuneyiit,

    by "stream is over" you mean the streamsocket is closed ?

    -> The stream is over means there is no more data coming and we can treat it as closed.

    is it possible to see the source code of DataReader ? I know it's native code but since you are at microsoft can you perhaps look at what DataReader.LoadAsync() does and how it does it using InputStream ?

    -> Sorry I don't think its possible. It's not open source yet :P

    --James


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Wednesday, April 8, 2015 12:48 AM
    Moderator