1

As I couldn't find any way to peek for data (read data without consuming the buffer) as asked at How to peek StreamSocket for data in UWP apps I'm now trying to make my own "peek" but still no luck.

I don't see how I can read data from StreamSocket in the manner which will let me use timeouts and leave the connection usable in case if timeout elapses.

In the end, the problem is as follows. In my, let's say, IMAP client, I get response from a server and if this response is negative, I need to wait a bit to see if the server immediately sends yet another response (sometimes, the server can do it, with extra details on the error or even a zero packet to close the connection). if the server didn't send another response, I'm fine, just leaving the method and returning to the caller. The caller can then send more data to the stream, receive more responses, etc.

So, after sending a request and getting initial response I need in some cases to read socket once again with a very small timeout interval and if no data arrives, just do nothing.

1 Answer 1

1

You can use a CancelationTokenSource to generate a timeout and stop an async operation. The DataReader consumes the data from the input stream of the StreamSocket. Its LoadAsync() method will return when there is at least one byte of data. Here, we are adding a cancellation source that will cancel the asynchronous task after 1 second to stop the DataReader.LoadAsync() if no data has been consumed.

var stream      = new StreamSocket();

var inputStream = stream.InputStream;

var reader      = new DataReader(inputStream);
reader.InputStreamOptions   = InputStreamOptions.Partial;

while(true)
{
    try
    {
        var timeoutSource   = new CancellationTokenSource(TimeSpan.FromSeconds(1));
        var data    = await reader.LoadAsync(1).AsTask(timeoutSource.Token);

        while(reader.UnconsumedBufferLength > 0)
        {
            var read    = reader.ReadUInt32();
        }
    }
    catch(TaskCanceledException)
    {
        // timeout
    }
}

Do no forget that disposing the DataReader will close the stream and the connection.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. But how can I then get rid of DataReader once it's done its job? I'll then need to return the connection to the caller in the same state as before. Ideally, I need to be able to attach it to the existing connection and detach it multiple times during the connection lifetime.
You can detach the Stream from the reader using DetachStream() : learn.microsoft.com/en-us/uwp/api/…. This will allow you to keep the Stream open when disposing the reader.
Oops, when checking on DataReader, I found that I'm already using it in my other code for exactly the same purpose and it seems I completely forgot that I've already solved this task earlier, just a few months ago.. Unbelievable..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.