带有一串流的异步I / O(BeginWrite / BeginRead)有什么影响?

时间:2009-11-04 06:10:32

标签: .net asynchronous filestream

假设我有一连串的流,那就是压缩 - >加密 - >文件I / O.

在C#中,使用同步I / O,它看起来像这样:

  int n=0;
  byte[] buffer= new byte[2048];
  string inputFileName = "input.txt";
  string outputFileName = inputFileName + ".compressed.encrypted";
  using (FileStream inputFileStream = File.Open(inputFileName, FileMode.Open, FileAccess.Read))
  {
      using (FileStream outputFileStream = File.Open(outputFileName, FileMode.Create, FileAccess.ReadWrite))
      {
          using (Stream encryptor = new EncryptingStream(fs))
          {
              using (Stream compressor = new CompressorStream(encryptor))
              {
                  while ((n = inputFileStream.Read(buffer, 0, buffer.Length)) > 0)
                  {
                      compressor.Write(buffer, 0, n);
                  }
              }
          }
      }
  }

为了利用FileStream提供的异步I / O,我想我不能简单地在压缩器流上使用BeginWrite()方法。

在这个例子中,为了利用FileStream上的异步I / O,我认为EncryptingStream需要通过在包装的Stream上调用BeginWrite / EndWrite来实现Write。如果包装的Stream是FileStream,那么我将获得异步I / O.这是对的吗?

1 个答案:

答案 0 :(得分:2)

在外部流(此处为BeginWrite)上调用compressor将成功将工作移至线程池,从而使其相对于调用方法异步执行。这可能适合您的应用,但它不是最大可能的效率。正如您所指出的,BeginWrite不会在实际执行磁盘I / O的内部FileStream上使用。在BeginWrite使用FileStream时,BeginWrite的{​​{1}}实现利用了“Windows完成端口API”,提供了更高的可伸缩性。

另一种看待这种情况的方法是从操作系统的角度来看,它不是异步I / O.但是,它将在线程池线程上同步运行,从而有效地使其与所有其他代码异步。要真正利用操作系统异步I / O,您需要在可以使用完成端口API的类上调用BeginWrite

我不确定你正在使用什么样的压缩,所以拿一粒盐就可以了。例如,您使用的Stream可能甚至不实现BeginWrite,或者它可能会同步实现它。