我在使用filesystemwatcher时遇到问题,这让我发疯了。
原来我正在观察文件夹中的新文本文件,当Created Event被引发时,我基本上使用以下代码阅读它:
string txtTemp = File.ReadAllText(MyFilePath);
之后,我处理txtTemp字符串中的数据,基本上我读了它的行&将数据存储在DB上,非常简单不是吗?
问题是当在这个过程中引发异常时(假设数据库连接失败),如果我抓住它并不重要,因为对于下一个即将到来的文件,应用程序将抛出异常说
“进程无法访问文件'theNewComingFile.txt',因为它是 被另一个进程使用。“
如果新创建的文件甚至没有被打开或读过,它怎么可能正在使用?并且应用程序不断抛出所有新文件的“进程无法访问文件”异常。
我们唯一能做的就是关闭并重新打开应用程序,这会重置应用程序,一切正常,直到再次引发任何类型的异常> (天啊!)
有什么想法吗?任何解决方法?有什么想法吗?任何建议......任何事情?呵呵呵呵=)
谢谢老兄!!
答案 0 :(得分:5)
您可以使用Sysinternals Process Explorer开始调查。它将为您提供更多详细信息,尤其是关于哪个进程保存文件。
答案 1 :(得分:2)
在完成文件完成之前触发Created事件。
来自MSDN:
创建文件后立即引发OnCreated事件。如果是文件 被复制或转移到一个观察目录,OnCreated 将立即引发事件,然后是一个或多个OnChanged 事件
因此,获得您描述的异常将是相当正常的。当我遇到这种情况时,我基本上首先测试文件,看看我是否可以访问它。这是我使用的功能:
private static bool GetExclusiveAccess(string filePath)
{
try
{
using (FileStream file = new FileStream(filePath, FileMode.Append, FileAccess.Write))
{
file.Close();
return true;
}
}
catch (IOException)
{
return false;
}
}
如果您没有访问权限,则需要等待并再次检查。
答案 2 :(得分:2)
打开文件的行为可能会改变最后读取的时间戳:这可能会导致循环。
您可能希望尝试更改设计,以便在(并且仅当)文件尚未排队等待处理时将事件放入队列。然后,您可以在另一个线程的适当控制下捕获异常等,而不会妨碍观察者。
[我在过去看到了FileSystemWatcher
的一些非常有趣的角落案例 - 当它走投无路时它可能是一个野兽。当内部缓冲区溢出因为它被事件淹没时,一个(一段时间后)在Windows Server 2003中导致了一个不太可重现的蓝屏挂起。最好小心。]
答案 3 :(得分:-1)
解决方法很简单 - 将您的观察者放在自己的AppDomain中,拆除AppDomain并在处理异常时重新启动。这很可能会解决您的问题。但为什么会这样呢?我不得不考虑一下,也许找点什么。