背景
我有一个服务器,它有一个\\Server\Share
包含 4 个子文件夹的共享文件夹:
- 出站决赛
- 出站暂存
- 入站决赛
- 入站暂存
所有文件夹都驻留在同一个物理磁盘和分区上,不使用连接点。
我还有几个 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
直到文件夹中显示特定文件。
我已经阅读了几个关于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;
}
这是抛出异常的使用行。
问题
我会假设 fileWatcher.WaitForChanged 只有在具有正确 GUID 名称的文件位于\\Server\Share\InboundFinal
文件夹中时才会继续。这正是 FileSystemWatcher 在本地文件夹上的工作方式,但不适用于通过网络访问的文件共享(本地文件,即使通过共享访问,也倾向于工作)。FileSystemWatcher 报告线程正在等待的文件在 FileSystemWatcher\\Server\Share\InboundFinal
文件夹中。但是,当我尝试读取文件时,我得到了 FileNotFoundException。读取线程必须等待 3-15 秒才能读取文件。我尝试使用带有Read
共享的 FileStream 打开文件。
什么可能导致这种行为?我该如何解决它?理想情况下,FileSystemWatcher.WaitForChanged(WatcherChangeTypes.Changed | WatcherChangeTypes.Created, timeOut);
只有在可以读取文件或发生超时时才应继续执行。