Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream reading with await async

Tags:

c#

I have written the following method to read data from a stream in general. On my computer it's gonna be a MemoryStream, and in the real world, it's gonna be a network stream.

    public async void ReadAsync()
    {
        byte[] data = new byte[1024];
        int numBytesRead = await _stream.ReadAsync(data, 0, 1024);

        // Process data ...

        // Read again.
        ReadAsync();
    }

The idea here is that data gets processed in the callback, and the callback should then spawn a new reader-thread (and kill the old). This does not happen however. I get a StackOverflowException.

What am I doing wrong?

like image 723
kasperhj Avatar asked Nov 18 '25 01:11

kasperhj


2 Answers

You've got a never-ending recursion.

You're calling ReadAsync() forever and never return from the method (hence breaking the infinite recursion).

A possible solution is:

public async void ReadAsync()
{
    byte[] data = new byte[1024];
    int numBytesRead = await _stream.ReadAsync(data, 0, 1024);

    // Process data ...

    // Read again.
    if(numBytesRead > 0)
    {
        ReadAsync();
    }
}

To understand recursion better, check this.

like image 128
Filip Ekberg Avatar answered Nov 20 '25 17:11

Filip Ekberg


There are no threads directly involved here (see my intro to async/await).

Your StackOverflowException is caused (as it usually is) by recursion that goes too deep. Just re-write the method to be iterative:

public async Task ReadAsync()
{
  byte[] data = new byte[1024];

  while (true)
  {
    int numBytesRead = await _stream.ReadAsync(data, 0, 1024);
    if (numBytesRead == 0)
      return;

    // Process data ...
  }
}
like image 35
Stephen Cleary Avatar answered Nov 20 '25 15:11

Stephen Cleary



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!