evclay
evclay

Reputation: 57

How do I continue to read data from ReadAsync after I start processing the data?

I am new here and by no means an expert at c# programming.

I am writing an application that connects to a device over TCP. It sends the device a command and the device responds. Sometimes The device will send another message after it has responded to my command. For example if I say "Read Tag" It will respond with the tag value "Tag: abcdefg". But sometimes, after a couple of hundred milliseconds, it will respond with something like "Buffer Low: 14" telling me the size of its buffer.

Here is how I am currently receiving data:

            public Task<string> ReceiveDataAsync()
    {
        receiveBuffer = new byte[receiveBufferSize];
        Task<int> streamTask = _networkstream.ReadAsync(receiveBuffer, 0, receiveBufferSize);
        // Since the read is async and data arrival is unknown, the event
        // must sit around until there is something to be raised.
        var resultTask = streamTask.ContinueWith<String>(antecedent =>
        {
            Array.Resize(ref receiveBuffer, streamTask.Result);  // resize the result to the size of the data that was returned
            var result = Encoding.ASCII.GetString(receiveBuffer);
            OnDataReceived(new TCPEventArgs(result));
            return result;
        });
        return resultTask;
    }

I am confused about reading the network stream. When I use the ReadAsync method, and then I get something back, how do I handle the delay? In my mind, I get the first response of the tag data, then I start to work on that task. Even though I work on the task ".ContinueWith" will my stream continue to receive data? Will the task automatically go back and process more data as it comes in the stream? Do I need to call the ReceiveDataAsync method every time I think some data should be arriving or will it remain open until Dispose of the stream?

Upvotes: 1

Views: 2214

Answers (1)

Gildor
Gildor

Reputation: 2574

Yes, you need to call ReceiveDataAsync repeatedly, usually call it in callback of ContinueWith, or just put it in a loop if you use async/await, so that you read some data, process it and then go back to read (or wait) the next bytes.

Like this:

private static void OnContinuationAction(Task<string> text)
{
    Console.WriteLine(text);
    ReceiveDataAsync().ContinueWith(OnContinuationAction);
}

...

ReceiveDataAsync().ContinueWith(OnContinuationAction);

Or with async/await:

private async void ReceiveDataContinuously()
{
    while(true)
    {
        var text = await ReceiveDataAsync();
        Console.WriteLine(text);
    }
}

If you don't call ReadAsync on the stream repeatedly, as long as the underlying TCP connection is open it will continue receiving data into the buffer, but your program cannot get them.

Upvotes: 3

Related Questions