Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 创建用于网络共享的文件流速度极慢_C#_.net_Networking - Fatal编程技术网

C# 创建用于网络共享的文件流速度极慢

C# 创建用于网络共享的文件流速度极慢,c#,.net,networking,C#,.net,Networking,我有一个windows服务,它必须通过2个网络共享在大约20个文件中写入大约20kB的数据 使用Total Commander写入文件的时间:小于0.1s 使用我的应用程序编写文件的时间:ca 10s 怎么了?是的,文件不断从两个共享中读取,但这不应成为问题,因为: public void WriteData(string text, string fileName, bool forceBackup = false) { foreach (var dir in Locations) {

我有一个windows服务,它必须通过2个网络共享在大约20个文件中写入大约20kB的数据

使用Total Commander写入文件的时间:小于0.1s

使用我的应用程序编写文件的时间:ca 10s

怎么了?是的,文件不断从两个共享中读取,但这不应成为问题,因为:

public void WriteData(string text, string fileName, bool forceBackup = false) {
    foreach (var dir in Locations) {
        var path = string.Format(@"{0}\{1}", dir, fileName);
        FileStream stream = null;
        try {
            stream = new FileStream(
                path,
                FileMode.Create,
                FileAccess.Write,
                FileShare.Read
            );
            using (StreamWriter writer = new StreamWriter(stream)) {
                stream = null;
                writer.Write(text);
            }
        }
        catch (Exception) { } // irrelevant now, tested it doesn't throw exceptions anyway
        finally {
            if (stream != null) stream.Dispose();
        }
        File.SetLastWriteTime(path, DateTime.Now);
    }
}
上面的代码适用于本地文件。将所有数据写入RAM驱动器只需一毫秒。我的网络共享也位于RAM驱动器上

重要的是,使用Total Commander将这些文件复制到完全相同的位置也需要一毫秒的时间。我的意思是-在满负荷的情况下复制到网络共享

没有共享冲突,应用程序在单个线程中写入文件。从Total Commander写入这些文件时没有问题,在不使用网络共享的情况下使用我的应用程序写入这些文件时没有问题

没有共享冲突,因为在写入时-这些文件仅由web服务器读取,并显式设置了
FileAccess.READ
FileShare.ReadWrite

不,我不能在不使用网络共享的情况下写入这些文件,因为我的服务是在两台服务器之间进行同步。不,我不能使用DFSR,因为文件更新太频繁(每秒2次)。不,我不能使用两个单独的服务来更新两台机器上的文件,因为这会取消故障保护功能,因为我的服务的每个实例都可以在两台服务器上停止数据更新的情况下停止

具体地说,在我的生产环境中,此服务有两个实例,一个实例在更新文件,另一个实例持续监视活动实例是否执行其任务。当检测到故障时,他们会切换角色。这一切都是实时发生的,而且很有魅力。有一个巨大的问题:写文件的时间过长

如果您想知道
File.SetLastWriteTime()
代表什么-当文件上次写入时间未单独使用create/write正确更新时,这是Windows(.NET)错误的一个解决方法。当然,如果第一个实例正在及时更新文件,那么正确的修改时间对于另一个实例检测是至关重要的

另外:据报道,有时会从这些文件中读取一些垃圾。但这种情况很少发生。我还没有确认这个错误

但主要的问题是——什么花了这么长时间?我的测试服务器和目标服务器之间有快速的1GBit链路,生产服务器之间有10GBit链路。Ping低于1ms。这不是一个网络问题


经过更多的测试,我发现缓冲区大小和文件选项对写入时间没有任何影响。我发现网络ping非常重要。我无法在我的开发机器上测试代码,因为ping太大了

无论如何-如果所有文件都创建一次,然后在不重新创建流的情况下进行更新,那么代码可以优化为运行速度提高80%。与本地共享相比,它的速度也非常快。无论如何-测试代码很快,同一服务器上的生产代码慢50倍。但是,有一点不同——生产文件由web服务器不断读取,而测试文件则不是

仍然没有达到目标。我需要在连接10GBit/s以太网的两台服务器上每秒更新两次20 x 1kb的文件。实现的200ms延迟是可以接受的,但它只适用于测试文件,对于共享的真实文件,每次更新我仍然可以获得6000ms以上的延迟

顺便说一句,在可靠性至关重要的情况下,让文件保持打开状态不是一个选项。该服务应该能够无缝地将所有更新切换到另一个实例,以防任何文件被删除,或者出现任何网络、数据库或磁盘错误。让文件保持打开状态可能会导致共享冲突、内存泄漏和其他灾难。正确处理不断打开的文件也会非常复杂,这会使代码更难调试


也许还有另一种在服务器之间共享数据的方法?也许一个zip文件可以用来上传文件,然后另一个服务会解压文件?我确信压缩和解压1kB的数据不会花费1秒的时间

我想你的问题的答案就在这篇帖子里:

为了直接回答这个问题,它以4kbyte块而不是64Kbyte块来编写文件,这将导致更多的往返

您应该能够更改此选项,请参见以下答案:


我错了,速度太慢了。事实并非如此。问题出在测试过程中。我已经将基准测试代码添加到我的生产服务中,结果显示它完全按照预期工作。我的代码中没有bug,系统中也没有滞后

一系列事件导致了这种情况:

  • 有个人打电话给我,我们的数据更新有很大的滞后(超过5秒)
  • 我在我的开发机器上运行了更新服务的调试版本,发现延迟几乎正好是5到6秒
  • 我创建了这个post和测试项目,它编写测试文件并测量时间
  • 我在一台生产服务器上测试了代码,以确保它工作正常,没有大的延迟
  • 我将基准测试代码添加到生产服务中,以查看它在现实生活中的表现(并且表现完美)
  • 我给那个给我打电话的人打了电话,问他是否看到了滞后——他说现在没有滞后
  • 什么?!嗯,可能是他的网络滞后!我的错!我应该从一开始就在生产服务器上测试代码。当网络连接速度和延迟对进程至关重要时,程序无法在任何其他环境中进行测试,或者可以进行测试,但速度或延迟不是。可能如果我有一个更大的文件,差异就不那么显著了,但是有20个小文件,我的机器和生产服务器之间的差异是巨大的

    顺便说一句,
    WriteData
    方法是最佳的,没有任何改变