简体   繁体   English

C#System.IO.FileStream性能严重挂起(超过10秒)

[英]C# System.IO.FileStream performance hangs badly (10+ seconds)

I'm running into an issue wherein I am getting significant (10+ second) delays when performing file write operations. 我遇到一个问题,其中在执行文件写入操作时出现严重的延迟(10秒以上)。 It seems only to happen once, and always happens during the 2nd (or sometimes 3rd?) call to the WriteToFile() function. 它似乎只发生一次,并且总是在对WriteToFile()函数的第二次(有时是第三次?)调用期间发生。

I've written out 3 different 'WriteToFile' functions to show some of the variations I've tried thus far + shown additional lines in 'OpenFileIfNecessary' that I've tried. 我已经写出3个不同的“ WriteToFile”函数来显示到目前为止我尝试过的一些变化,并在我尝试过的“ OpenFileIfNecessary”中显示其他行。

The code never throws an error, and the offsets/counts are all valid. 代码永远不会引发错误,并且偏移量/计数都有效。 Once the delays occur a single time, there seem to be no further delays. 一旦延迟发生了一次,似乎就没有进一步的延迟了。

This has been a pain in my side for 2+ days and I'm definitely at that point where I'm in need of a 2nd opinion. 这已经让我痛苦了2天多,而我绝对是需要第二种意见的时候。

    private void WriteToFile(byte[] data, long offset, int count)
    {
        lock (this.monitor)
        {
            this.OpenFileIfNecessary();
            this.fileStream.Seek(offset, SeekOrigin.Begin);  // <- Takes 10+ seconds for THIS line to execute
            this.fileStream.Write(data, 0, count);
        }
    }

    private void WriteToFile2(byte[] data, long offset, int count)
    {
        lock (this.monitor)
        {
            this.OpenFileIfNecessary();
            this.fileStream.Position = offset;    // <- Takes 10+ seconds for THIS line to execute 
            this.fileStream.Write(data, 0, count);
        }
    }

    private void WriteToFile3(byte[] data, long offset, int count)
    {
        lock (this.monitor)
        {
            var fileName = this.file.FullName;
            using (Stream fileStream = new FileStream(fileName, FileMode.OpenOrCreate))
            {
                fileStream.Position = offset;            //(instant execution of this line)
                fileStream.Write(data, 0, count);
                //Getting from HERE ->
            }
            //To HERE <- takes 10+ seconds
        }
    }

    private System.IO.FileStream fileStream = null;
    private System.IO.FileInfo file;  //value set during construction

    private void OpenFileIfNecessary()
    {
        lock (this.monitor) {
            if (this.fileStream == null) {
                //The following 3 lines all result in the same behavior described in this post

                //this.fileStream = this.file.Open(FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                //this.fileStream = this.file.Open(FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write);
                //this.fileStream = this.file.OpenWrite();
                this.fileStream = this.file.Open(FileMode.OpenOrCreate);                    
            }               
        }
    }

Found the issue. 找到了问题。 It's worth mentioning that we had previously been testing with smaller (<1GB files) until late last week. 值得一提的是,我们之前一直在使用较小的文件(小于1GB)进行测试,直到上周下半年为止。 With that in mind: 考虑到这一点:

We write to the file at different positions, that is, we don't simply start at position 0 and go to the end. 我们在不同位置写入文件,也就是说,我们不只是从位置0开始到结束。 What that means (especially for larger files) is that every time we first go to a position that is deep into the file, there is apparently a wait period for the newly extended size to be allocated. 这意味着(尤其是对于较大的文件而言)意味着,每次我们第一次进入文件深处时,显然都有一个等待时间来分配新扩展的大小。

The way FileStream obfuscates a lot of the under-the-hood stuff made it a little difficult to find the pattern, and once we did some deeper profiling and discovered smaller delays with smaller files (never noticed the delays before) it became clear what was happening. FileStream混淆了很多底层内容的方式使查找模式有些困难,并且一旦我们进行了更深入的分析并发现了较小文件的较小延迟(之前从未注意到过延迟),就清楚了发生。

The plan forward is to do some multithreading to allow for the space for the file to be allocated fully before writing to disk; 未来的计划是做一些多线程处理,以允许在写入磁盘之前完全分配文件空间。 we can buffer in memory during that wait period. 我们可以在那段等待时间内缓冲在内存中。

Example code for preallocating the entire file: 用于预分配整个文件的示例代码:

fileStream.Seek(size - 1, SeekOrigin.Begin);
fileStream.WriteByte(0);
fileStream.Flush();

That is happening because when you set a file position to some large value, underlying storage system has to zero out the contents of allocated blocks. 发生这种情况是因为当您将文件位置设置为某个较大的值时,基础存储系统必须将分配的块的内容清零。 I do not believe BCL will let you bypass that but there is actual a way in Win32 to skip that functionality which requires running program to have administrator privileges (in a very imprecise manner). 我不相信BCL会让您绕过它,但是Win32中确实存在一种跳过该功能的方法,该功能要求正在运行的程序具有管理员权限(以非常不精确的方式)。

Search for SetFileValidData() documentation. 搜索SetFileValidData()文档。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 System.IO.FileStream FileAccess与FileShare - System.IO.FileStream FileAccess vs FileShare 使用WildCard加载System.IO.FileStream - Load a System.IO.FileStream using a WildCard 如何使用System.IO.FileStream读取希伯来语文本? - How to read Hebrew text using System.IO.FileStream? System.IO.FileStream在巨大的文件上超级慢 - System.IO.FileStream is super slow on huge files System.IO.File.OpenRead工作正常,但是System.IO.FileStream不工作? - System.IO.File.OpenRead is working but System.IO.FileStream is not working? 无法将“System.Web.HttpInputStream”类型的对象转换为“System.IO.FileStream”MVC 3 - Unable to cast object of type 'System.Web.HttpInputStream' to type 'System.IO.FileStream' MVC 3 尝试保存图像的编译错误.NET Core - 参数类型'System.IO.FileStream'的参数类型无法分配参数类型 - Compilation error trying to save image .NET Core - Argument type 'System.IO.FileStream' is not assignable to parameter type 'System.IO.Stream' C#:FileStream.SetLength(long)失败,并显示“由于文件系统限制,请求的操作无法完成”(在Windows 10 Home,NTFS上) - C#: FileStream.SetLength(long) fails with “The requested operation could not be completed due to a file system limitation” (on Windows 10 Home, NTFS) Web服务中发生C#FileStream IO异常 - C# FileStream IO Exception occurs in Web Service System.IO对C#中OS的文件系统性能的影响 - System.IO effects on OS's file system performance in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM