异步读取未知数据长度

时间:2012-08-15 06:27:47

标签: c# stream network-programming task-parallel-library

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

到目前为止,我已使用BeginReadEndRead函数对以及递归AsyncCallback来管理此问题。这很好用,但我有点担心如果长度很长,它会如何缩放,因为如果所有读取同步完成,它有时会产生相当令人印象深刻的callstack。

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,我认为这会使这项任务变得更加顺畅。流本身通常是NetworkStreamSslStream

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

0 个答案:

没有答案