FileStream.BeginWrite优于FileStream.Write?

Phi*_*ght 6 .net c# asynchronous filestream

我需要对同一个文件进行一批写操作,但是在文件中的不同位置.我希望以最佳性能实现这一点,因此查看了同步FileStream.Write和异步FileStream.BeginWrite方法.

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

我已经使用了正确的构造函数,因此我可以要求异步操作创建的FileStream和我还测试这说明假,所以他们没有在一个异步的方式确实操作IAsyncResult.CompletedSynchronous财产.似乎使用Be​​ginWrite的唯一好处是你在写入时不会阻塞你的线程.除了这个好处之外,使用异步版本还有什么意义吗?

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

        // 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();
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 20

文件写入在Windows中进行了大量优化.您实际上没有写入磁盘,而是写入文件系统缓存.内存到内存的副本,以每秒5千兆字节或更高的速度运行.然后,从缓存中,数据被懒惰地写入磁盘.反过来优化以最小化写头移动的数量.

这几乎不可能通过异步写入进行优化.确实需要更长的时间,抓住线程池线程以使回调不是免费的.这里异步的好处是最小化主线程延迟,而不是实际上使其更有效.只有在编写大量数据时才能获得实惠.不仅适合缓存.此时,写入perf将从5 GB /秒下降到小于~50 MB /秒的悬崖,因为缓存空间只能以可写入磁盘的速率变为可用.

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