C#/ .NET的惰性流

eri*_*len 4 .net c# stream lazy-evaluation

有谁知道.net中的延迟流实现?IOW,我想创建一个像这样的方法:

public Stream MyMethod() {
    return new LazyStream(...whatever parameters..., delegate() {
        ... some callback code.
    });
}
Run Code Online (Sandbox Code Playgroud)

当我的其他代码调用MyMethod()返回以检索流时,它实际上不会执行任何工作,除非有人实际尝试从该流中读取数据。通常的方法是使MyMethod将stream参数作为参数,但是在我的情况下不起作用(我想将返回的流提供给MVC FileStreamResult)。

为了进一步说明,我正在寻找的是创建一系列分层的转换,因此

数据库结果集=(已转换为)=>字节流=(已链接至)=> GZipStream =(已传递)=> FileStreamResult构造函数。

结果集可能很大(GB),所以我不想将结果缓存在MemoryStream中,可以将其传递给GZipStream构造函数。相反,我想在GZipStream请求数据时从结果集中获取。

Ree*_*sey 5

本质上,大多数流实现都是惰性流。通常,任何流在流的用户请求之前都不会从其源中读取信息(除了一些额外的“过度读取”以允许发生缓冲之外,这使得流的使用要快得多)。

如果需要完全惰性的流实现,则通过重写Read来打开基础资源,然后在使用时从该资源中进行读取,可以使Stream实现在需要之前不进行读取的过程相当容易。只需重写Read,CanRead,CanWrite和CanSeek。


drz*_*aus 0

这个答案(/sf/answers/1543420021/)链接到这篇关于如何编写自己的流类的文章。

引用一下答案:

生产者将数据写入流,消费者读取。中间有一个缓冲区,以便生产者可以“提前写入”一点。您可以定义缓冲区的大小。

引用原始出处:

您可以将 ProducerConsumerStream 视为具有 Stream 接口的队列。在内部,它被实现为循环缓冲区。两个索引跟踪缓冲区内的插入点和删除点。字节写入 Head 索引,并从 Tail 索引中删除。

如果 Head 绕到 Tail,则缓冲区已满,生产者必须等待读取一些字节才能继续写入。类似地,如果 Tail 追上了 Head,消费者必须等待字节写入才能继续。

本文继续描述了指针回绕时的一些奇怪情况,并提供了完整的代码示例。