65.9K
CodeProject 正在变化。 阅读更多。
Home

CoStream,无缓冲管道流

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2014年12月15日

CPOL

1分钟阅读

viewsIcon

14290

downloadIcon

157

这是“PipeStream,一种内存高效且线程安全的流”的替代方案。

引言

CoStreamPipeStream 的无缓冲替代方案。

背景

在生产者/消费者模式中,如果我们知道存在一个保证读取 stream 到末尾,或者在无法读取的情况下将其释放的消费者,那么同步 stream 不需要维护其自身的内部缓冲区,完全依赖于 Read 方法的调用者提供的缓冲区。 在 Read 方法中,CoStream 保存对目标缓冲区的引用,并等待其被填充。 Write 方法另一方面,将数据从源缓冲区复制到目标缓冲区,如果缓冲区准备就绪则向读取者发出信号,如果源缓冲区中还有未消耗的数据,则等待另一个 Read 调用,或者返回到 Write 调用者。

Using the Code

CoStream 不能在单个线程中使用。 应该至少有两个线程,读取和写入线程。 两者都需要关闭(或释放)stream,以便对方可以在末尾恢复。

您将在附带的归档文件中找到的测试程序将一些 XML 文件加载到 XmlDocument 中,然后将其写入 CoStream 的实例。

    static CoStream costream = new TestCoStream();
    static string outpath;

    static void Main(string[] args)
    {
      // ...

      XmlDocument doc = new XmlDocument();
      doc.Load(args[0]);
      outpath = args[1];

      var reading_thread = new Thread(ReaderBody);
      reading_thread.Start();

      using (var pipe = XmlWriter.Create(costream, new XmlWriterSettings { CloseOutput = true }))
        doc.Save(pipe);

      reading_thread.Join();
    }

读取线程只是将其复制到输出文件。

    static void ReaderBody()
    {
      using (var reader = XmlReader.Create(costream, new XmlReaderSettings { CloseInput = true }))
      using (var writer = XmlWriter.Create(outpath))
        writer.WriteNode(reader, false);
    } 

TestCoStream 类重写了 CoStreamReadWriteFlush 方法,以显示后台发生的情况。

使用比 XmlReaderXmlWriter 的默认实现使用的内部缓冲区更长的示例 XML 输入文件运行该程序(例如,这个:http://www.w3.org/2001/xml.xsd)将产生类似的结果

<Writing 6143 bytes.
>Reading 4096 bytes.
>4096 bytes read.
>Reading 4096 bytes.
<Written.
<Writing 2163 bytes.
>4096 bytes read.
>Reading 4096 bytes.
<Written.
<Flushing.
>114 bytes read.
>Reading 4096 bytes.
<Writing 0 bytes.
<Written.
<Flushing.
<Writing 0 bytes.
<Written.
<Flushing.
>0 bytes read.

历史

  • 2014-12-14 - 版本 1.0
© . All rights reserved.