2

我已经编写了以下方法来从一般的流中读取数据。在我的计算机上,它将是一个 MemoryStream,而在现实世界中,它将是一个网络流。

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

        // Process data ...

        // Read again.
        ReadAsync();
    }

这里的想法是数据在回调中得到处理,然后回调应该产生一个新的读取器线程(并杀死旧的)。然而,这不会发生。我得到一个 StackOverflowException。

我究竟做错了什么?

4

3 回答 3

12

你有一个永无止境的递归

您一直在调用ReadAsync()并且永远不会从该方法返回(因此打破了无限递归)。

一个可能的解决方案是:

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();
    }
}

要更好地理解递归,请检查此

于 2012-09-04T13:52:05.123 回答
8

这里没有直接涉及线程(参见我对async/的介绍await)。

StackOverflowException是由太深的递归引起的(通常是这样)。只需将方法重写为迭代即可:

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 ...
  }
}
于 2012-09-04T14:35:58.443 回答
3

您至少需要检查流中是否有数据,重复操作或您的递归永远不会停止

// Read again.
if(numBytesRead != 0)
    ReadAsync();
于 2012-09-04T13:54:12.020 回答