【问题标题】:FileStream.BeginWrite advantages over FileStream.Write?FileStream.BeginWrite 优于 FileStream.Write?
【发布时间】:2011-10-11 23:15:03
【问题描述】:

我需要在文件中的不同位置对同一个文件进行一批写入。我想以可能的最佳性能实现这一目标,因此查看了同步 FileStream.Write 和异步 FileStream.BeginWrite 方法。

同步实现很简单,只需在循环中调用 FileStream.Write 所需的次数。异步版本在循环中调用 FileStream.BeginWrite,然后执行 WaitHandle.WaitAll 以阻塞直到它们全部完成。令我惊讶的是,这比简单的同步版本要慢。

我使用正确的构造函数创建了 FileStream,因此我可以请求异步操作,并且我还测试了指示 False 的 IAsyncResult.CompletedSynchronous 属性,因此它们确实以异步方式操作。似乎使用 BeginWrite 的唯一好处是在写入发生时您不会阻塞线程。除了这个好处之外,使用异步版本还有什么意义吗?

这是我用来玩异步方法的测试代码,可能有明显的错误?

        // Size of a chunk to be written to file
        var chunk = 1024 * 64;

        // Number of chunks to write async
        var reps = 32;

        // Create new file and set length
        var fs = new FileStream(@"C:\testfile.dat", 
                                FileMode.Create, FileAccess.ReadWrite, 
                                FileShare.None, chunk, true);
        fs.SetLength(chunk * reps);

        // Allocate resources
        byte[] bytes = new byte[chunk];
        WaitHandle[] handles = new WaitHandle[reps];

        for (int i = 0; i < reps; i++)
        {
            fs.Seek(chunk * i, SeekOrigin.Begin);
            handles[i] = fs.BeginWrite(bytes, 0, chunk, null, null).AsyncWaitHandle;
        }

        // Wait for all async operations to complete
        WaitHandle.WaitAll(handles);

        fs.Flush();
        fs.Close();

【问题讨论】:

  • 您是否有任何特殊原因必须进行多次 BeginWrite 调用?
  • 我的实际代码需要写入文件的不同部分,因此实际上每个部分都会寻找不同的位置然后写入。

标签: c# .net asynchronous filestream


【解决方案1】:

文件写入在 Windows 中得到了高度优化。您实际上并没有写入磁盘,而是写入文件系统缓存。内存到内存的副本,以每秒 5 GB 或更高的速度运行。然后从缓存中将数据延迟写入磁盘。进而进行优化以最大限度地减少写入磁头移动的次数。

这几乎不可能通过异步写入进行优化。这确实需要更长的时间,抓住线程池线程来进行回调并不是免费的。此处异步的好处是最大限度地减少主线程延迟,而不是实际上使其更高效。只有当您写入大量数据时,您才会真正受益。超过将适合缓存。到那时,写入性能将从 5 GB/秒急剧下降到小于 ~50 MB/秒,因为缓存空间只能以磁盘写入的速度可用。

很难预测何时会发生这种情况。这取决于机器有多少内存以及其他进程需要多少内存。当你写一个千兆字节或更少时,你基本上不用担心它。重要的是,当异步写入挂起时,您实际上有一些有用的事情要做。等待他们完成就失去了使用它的意义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多