3

我想实现从 a 读取的异步读取,Stream直到找到特定的终止字节。我真的不知道在找到给定字节之前我必须阅读多长时间,我想避免让线程等待结果。其他东西稍后会读取相同的流,这意味着我不能在终止字节之后读取太远。

到目前为止,我已经使用BeginReadandEndRead函数对和递归AsyncCallback. 这很好用,但我有点担心如果长度很长,这将如何扩展,因为如果所有读取同步完成,它有时会产生相当令人印象深刻的调用堆栈。

public void ReadUntilSpecificByte(Stream stream, byte terminator, Action<byte[]> onComplete)
{
    var output = new List<byte>();
    var buffer = new byte[1];
    Action[] readAction = { null };
    readAction[0] = () => stream.BeginRead(buffer, 0, 1, asyncResult =>
        {
            stream.EndRead(asyncResult);
            if (buffer[0] == terminator)
            {
                onComplete(output.ToArray());
            }
            else
            {
                output.Add(buffer[0]);
                readAction[0]();
            }
        }, stream);
    readAction[0]();
}

我是否在担心可能不是问题的事情,或者这是否可以以更智能的方式编写,以在更多的堆栈空间中运行?不幸的是,我不能使用 c# 4.5,我认为这会使这项任务更加顺利。流本身通常是 aNetworkStream或 a SslStream

编辑:我采用了 Marc 建议的方法,并为所有读取做了一个内部缓冲区,保持 2k 缓冲区。这是一个可行的解决方案,可能会更好地利用潜在的昂贵读取,因为它总是从底层套接字读取尽可能多的内容。如果可以避免这种情况仍然会很酷,但我想这是完全异步的代价的一部分。

4

0 回答 0