【发布时间】:2018-12-18 22:44:11
【问题描述】:
我正在使用此代码来监控特定文件夹中文件的创建:
_watcher = new RecoveringFileSystemWatcher(SourceFolder, "*.xml");
_watcher.Created += (_, e) =>
{
ProcessFile(e.Name);
};
RecoveringFileSystemWatcher 是一个 fileSystemWatcher 包装器。它的构造函数是:
public RecoveringFileSystemWatcher (string path, string filter)
{
_containedFSW = new FileSystemWatcher(path, filter);
}
进程按预期工作,但对于某些文件,随机抛出异常,告知该文件已被另一个进程使用。
这是在文件创建时启动的方法:
var nfo = new FileInfo(filePath);
if (nfo.Exists)
{
var archivoXml = nfo.Name;
string archivo = String.Empty;
try
{
string content = Task.Run(async () => await GetFileContent(filePath)).Result;
if (String.IsNullOrEmpty(content))
return false;
XmlDocument xml = new XmlDocument();
xml.LoadXml(content);
//The rest of the method
}
}
GetFileContent 方法是这样的:
private async Task<string> GetFileContent(string filePath)
{
string content = String.Empty;
try
{
Console.Write("ONE - "); InfoLog.Save($"ONE {filePath}");
using (StreamReader sr = new StreamReader(filePath))
{
Console.Write("TWO - "); InfoLog.Save($"TWO {filePath}");
content = await sr.ReadToEndAsync().ConfigureAwait(false);
Console.Write($"THREE {(sr.BaseStream == null ? "Closed" : "Opened")} - "); InfoLog.Save($"THREE {(sr.BaseStream == null ? "Closed" : "Opened")} {filePath}");
sr.Close();
Console.WriteLine($"FOUR {(sr.BaseStream == null ? "Closed" : "Opened")}"); InfoLog.Save($"FOUR {(sr.BaseStream == null ? "Closed" : "Opened")} {filePath}");
}
}
catch (Exception ex)
{
InfoLog.Save($"XML file could be read -> {filePath}. See error log.");
ErrorLog.Save(ex);
}
return content;
}
看我写的日志信息调试进程。
我收到了一个名为 1112186.xml.xml 的文件的案例......这记录在日志中:
18/12/2018 19:12:10 ONE D:\GestorDocumental\Origen\1112186.xml
18/12/2018 19:12:10 XML file could not be read -> D:\GestorDocumental\Origen\1112186.xml. See error log.
如您所见,异常是在“使用”指令处引发的。
如果我看到完整的日志,我可以看到该文件 1112186.xml 以前从未使用过,因此唯一的机会是 FSW 保持该文件处于打开状态。我不知道为什么,但似乎正在发生这种情况。
很明显,这个进程正在锁定文件,因为当我退出控制台应用程序然后再次运行时,文件可以被处理。
对此有什么帮助吗?
谢谢 詹姆
【问题讨论】:
-
Jaime,我假设这些是外部写入的文件,您正在监视它们。很可能该文件已被锁定以进行写操作。建议您在代码中添加重试机制并过滤异常类型。在 I/O 代码中遇到这些问题并不罕见。
-
您可以添加延迟。 Thread.Sleep 并再次检查..看我的答案,
-
@PaulThomas 你是对的......这是一台扫描文档并将其放置在该文件夹中的打印机。奇怪的是,这并不总是发生,而只是随机发生。也许打印机在写入文件时没有关闭文件?我可以在我的程序中做些什么?
-
Jamie, @Guaravsa 在下面提供了一个合适的答案。建议您朝着这个方向前进,并记住 I/O 始终需要弹性代码方法。假设它会第一次失败:)
标签: c# filesystemwatcher