【发布时间】:2026-02-08 10:15:01
【问题描述】:
背景
我的服务器有一个共享文件夹 \\Server\Share 和 4 个子文件夹:
- OutboundFinal
- OutboundStaging
- 入站决赛
- 入站暂存
所有文件夹都驻留在同一个物理磁盘和分区上,不使用连接点。
我还有几个 WinForms 客户端(最多 10 个)向此共享写入和读取文件,每个客户端都在多个线程上工作(最多 5 个)。文件由客户端(总共最多 50 个线程)写入\\Server\Share\OutboundStaging 文件夹。每个文件都有一个 GUID 的名称,因此不会被覆盖。一旦文件被完全写入,它就会被客户端移动到\\Server\Share\OutboundFinal 文件夹。在同一台服务器上运行的 Windows 服务会将其拾取、删除、处理,然后将同名文件写入\\Server\Share\InboundStaging 文件夹。文件完全写入后,服务将移动到\\Server\Share\InboundFinal 文件夹。
此 \\Server\Share\InboundFinal 文件夹由每个 WinForms 客户端的每个线程使用 FileSystemWatcher.WaitForChanged(WatcherChangeTypes.Changed | WatcherChangeTypes.Created, timeOut); 进行监控
FileSystemWatcher.Filter 设置为某个线程希望在 \Server\Share\InboundFinal 文件夹中看到的文件的 GUID 文件名,因此 FileSystemWatcher 会一直等待,直到文件夹中显示特定文件。
我已经阅读了几个关于 FileSystemWatcher 行为异常且未报告 UNC 共享更改的 SO 问题。但对我来说不是这样。
我使用的代码如下所示:
FileSystemWatcher fileWatcher = new FileSystemWatcher();
fileWatcher.Path = InboundFinalFolder;
fileWatcher.Filter = GUIDFileName; // contains full UNC path AND the file name
fileWatcher.EnableRaisingEvents = true;
fileWatcher.IncludeSubdirectories = false;
var res = fileWatcher.WaitForChanged(WatcherChangeTypes.Changed | WatcherChangeTypes.Created, timeOut);
if (!fileWatcher.TimedOut)
{
using (FileStream stream = fi.Open(FileMode.Open, FileAccess.Read, FileShare.Read)) {
byte[] res = new byte[stream.Length];
stream.Read(res, 0, stream.Length);
return res;
}
这是抛出异常的 using 行。
问题
我假设 fileWatcher.WaitForChanged 只有在具有正确 GUID 名称的文件位于 \\Server\Share\InboundFinal 文件夹中时才会继续。这正是 FileSystemWatcher 在本地文件夹上的工作方式,但不适用于通过网络访问的文件共享(本地文件,即使通过共享访问,也倾向于工作)。 FileSystemWatcher 报告线程正在等待的文件位于 FileSystemWatcher \\Server\Share\InboundFinal 文件夹中。但是,当我尝试读取文件时,我得到了 FileNotFoundException。读取线程必须等待 3-15 秒才能读取文件。我尝试使用 Read 共享的 FileStream 打开文件。
什么可能导致这种行为?我该如何解决它?理想情况下,FileSystemWatcher.WaitForChanged(WatcherChangeTypes.Changed | WatcherChangeTypes.Created, timeOut); 应该仅在可以读取文件或发生超时时继续执行。
【问题讨论】:
-
FileNotFoundException 非常基本。一个标准错误是使用 GUIDFileName 打开文件。不够好,它不是一条完整的路径。测试时偶然工作,从不在服务器上工作。也可以在禁用反恶意软件的情况下尝试此操作,以防万一它认为在扫描文件时隐藏文件是个好主意。您没有发布实际失败的代码,所以这些只是猜测。
-
GUIDFileName 属性包含完整的 UNC 路径和 GUID 文件名。抱歉,我在我的问题中编辑了代码 sn-p 以澄清。
-
抛出异常的是 using 行。
标签: multithreading filesystemwatcher shared-directory windows-share