C# 使用wait-async进行流读取

C# 使用wait-async进行流读取,c#,C#,我编写了以下方法来从流中读取数据。在我的电脑上,这将是一个记忆流,而在现实世界中,这将是一个网络流 public async void ReadAsync() { byte[] data = new byte[1024]; int numBytesRead = await _stream.ReadAsync(data, 0, 1024); // Process data ... // Read again.

我编写了以下方法来从流中读取数据。在我的电脑上,这将是一个记忆流,而在现实世界中,这将是一个网络流

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

        // Process data ...

        // Read again.
        ReadAsync();
    }
这里的想法是在回调中处理数据,然后回调应该产生一个新的读取器线程(并杀死旧线程)。 然而,这并没有发生。我得到一个StackOverflowException

我做错了什么?

你有个没完没了的计划

您将永远调用
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();
    }
}

为了更好地理解递归,您至少需要检查流中是否有数据,重复操作或递归永不停止

// Read again.
if(numBytesRead != 0)
    ReadAsync();

这里没有直接涉及的线程(请参阅我的
async
/
wait
)介绍)

您的
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 ...
  }
}

执行不是在等待时停止,方法的其余部分不是用作回调吗?因此,在回调中调用ReadAsync。如果numBytesRead为0,那么我将永远无法读取更多的流。我想继续监听传入的数据。@lejon,这是一个延续块,是的。任务完成后,您将在等待部分之后返回。但随后您将立即再次调用“
ReadAsync
”。如果
numBytesRead
为零,则无法阻止您再次尝试阅读。有道理吗?如果您想通过网络等待传入数据,那是另一个问题。是的。这很有道理。谢谢你指出这一点。那么,我该如何等待传入的数据呢?没问题。查看关于如何在数据到达时等待数据的信息ti
NetworkStream
:它在大型数据传输中不会溢出吗?如果是这样,它现在不再是异步的了,不是吗?@Frederic:不确定你的意思。正如方法签名清楚显示的那样,它仍然是异步的。