复制到网络共享后尝试打开文件时偶尔出现“文件正在被另一个进程使用”

问题描述 投票:0回答:1

在我们的应用程序中,我们有一个 ASP.NET Web 服务器和一个 API 服务器来承担各种工作。在此特定工作流程中,用户上传 Web 服务器复制到网络共享的文件以供作业服务器使用。作业服务器通过每秒扫描一次 MSSQL 表中的新行来通知此情况。今年的某个时候,在集成测试期间,该流程开始随机失败:

System.IO.IOException: The process cannot access the file '\\a\\b\\c.xlsx' because it is being used by another process."

本地开发人员和质量检查人员从未遇到过此问题,但我认为这是因为他们的共享文件夹放置在各自的工作计算机上。当共享文件夹从本地文件系统移动到网络共享时,开始出现相同的异常。

我可以使用这个简短的应用程序在随机场合进行重现:

static void Main(string[] args)
{
    const string DestinationDirectory = "\\\\10.122.xxx.xxx\\Testing";

    var inputPath = args[0];
    var filename = Path.GetFileName(inputPath);
    var destinationPath = Path.Combine(DestinationDirectory, filename);

    Console.WriteLine(filename);

    Console.WriteLine("Copying the source file...");
    File.Copy(inputPath, destinationPath, true);

    Console.WriteLine("Opening the destination file...");
    try
    {
        using var _ = File.Open(destinationPath, FileMode.Open, FileAccess.Read);
        Console.WriteLine("Success!");
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex);
    }
}

如果我用这个批处理脚本运行它,我大约有十分之一的机会遇到异常。

@echo off

for /l %%x in (1, 1, 10) do (
    FileShareDemo.exe "C:\a\b\c\myfile"
)
myfile
Copying the source file...
Opening the destination file...
System.IO.IOException: The process cannot access the file '\\10.122.xxx.xxx\Testing\myfile' because it is being used by another process.
   at Microsoft.Win32.SafeHandles.SafeFileHandle.CreateFile(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategyCore(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize, Nullable`1 unixCreateMode)
   at System.IO.File.Open(String path, FileMode mode, FileAccess access)
   at FileShareDemo.Program.Main(String[] args)
  • 根据我的测试,该文件似乎被锁定了很短的时间,因此具有偶发性。
  • .NET 6 和 .NET 8 上存在问题。
  • 这很可能是与 Windows 相关的问题,但运行此批处理脚本:
@echo off

set file=myfile
set source="C:\a\b\c\%file%"
set destination="\\10.122.xxx.xxx\Testing\%file%"

for /l %%x in (1, 1, 10) do (
    echo Copying...
    copy %source% %destination%
    
    echo Reading...
    type %destination%
    REM powershell -command "Get-Content %destination% -Encoding byte -TotalCount 2"
)

执行相同的命令,不会触发错误,所以我相信它与.NET相关。

我尝试使用 Microsoft 的 Handle 实用程序来查找文件打开之前和之后的所有文件关联句柄,但应用程序太慢而无法注册它们。

c# windows .net-core file-io network-share
1个回答
0
投票

Windows 上的某些东西似乎会在最短的时间内锁定新文件,解决方案是在短时间内尝试再次访问该文件。我们延迟了 5 秒,此后问题就消失了。

© www.soinside.com 2019 - 2024. All rights reserved.