C# FileSystemWatcher行为不一致
我已经在设计器中设置了所有FSW属性(EnableRaisingEvents=true,filter=*.tif,IncludeSubdirectories=true,path=bla\bla\bla) 该应用程序在Windows Server 2008 R2标准计算机上运行,并监视本地文件夹中创建的文件。我使用计算机网络名“格雷厄姆”,而不是“C:\” 问题是,当文件被创建/移动到监视目录时,FSW并不总是触发。看起来有时候是这样,但大多数时候不是这样 在调试和查看我的机器上的文件夹时,也会出现一些奇怪的行为。如果我远程控制服务器机器并将文件移动到监视的文件夹,则不会发生任何事情。但如果我将文件从共享网络文件夹移动到监视的文件夹中,FSW每次都会触发 这使得我很难找到错误/bug。有人有什么想法吗 这就是所有的代码:C# FileSystemWatcher行为不一致,c#,winforms,filesystemwatcher,C#,Winforms,Filesystemwatcher,我已经在设计器中设置了所有FSW属性(EnableRaisingEvents=true,filter=*.tif,IncludeSubdirectories=true,path=bla\bla\bla) 该应用程序在Windows Server 2008 R2标准计算机上运行,并监视本地文件夹中创建的文件。我使用计算机网络名“格雷厄姆”,而不是“C:\” 问题是,当文件被创建/移动到监视目录时,FSW并不总是触发。看起来有时候是这样,但大多数时候不是这样 在调试和查看我的机器上的文件夹时,也会出
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace Ekonomikompetens_unikt_namn
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void fileSystemWatcher1_Created(object sender, System.IO.FileSystemEventArgs e)
{
StringBuilder log = new StringBuilder();
try
{
log.Append("--------------------").AppendLine().Append(DateTime.Now).AppendLine().Append("--------------------").AppendLine();
FileInfo file = new FileInfo(e.FullPath);
while (IsFileLocked(file))
{
System.Threading.Thread.Sleep(300);
}
string oFile = e.FullPath;
string nFile = oFile.Insert(oFile.Length - 4, "_" + DateTime.Now.ToString().Replace(" ", "").Replace("-", "").Replace(":", "")).Replace("\\XML Konvertering", "").Replace(@"\\GRAHAM\AnyDoc Invoices", @"\\FAKTURASERVER\AnyDoc");
if (!Directory.Exists(nFile.Substring(0, nFile.LastIndexOf('\\'))))
{
Directory.CreateDirectory(nFile.Substring(0, nFile.LastIndexOf('\\')));
File.Move(oFile, nFile);
Directory.Delete(oFile.Substring(0, oFile.LastIndexOf('\\')));
}
else
{
File.Move(oFile, nFile);
}
log.Append("* Moved and stamped file: ").AppendLine().Append(oFile).Append(" to ").Append(nFile).AppendLine().Append("--------------------").AppendLine();
}
catch (Exception x)
{
log.AppendLine().Append("*** ERROR *** ").Append(x).AppendLine().AppendLine();
}
finally
{
TextWriter tw = new StreamWriter(@"C:\tidslog\log.txt", true, Encoding.Default);
//TextWriter tw = new StreamWriter(@"C:\PROJEKT\tidsstämplarn\log.txt", true, Encoding.Default);
tw.Write(log);
tw.Dispose();
}
}
protected virtual bool IsFileLocked(FileInfo file)
{
FileStream stream = null;
try
{
stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (IOException)
{
return true;
}
finally
{
if (stream != null)
stream.Close();
}
return false;
}
}
}
注意:try-catch-finally可能做得不太好,但我对编码还不太熟悉,也不确定如何“捕获”这些东西,尽管记录器从未记录过错误。由于FSW从不开火,因此不会发生错误。我猜。订阅活动并检查错误(如果有)
如果正在创建或更改大量文件,请执行此操作 1>增加 医生说: 增加缓冲区的大小可以防止丢失文件系统 改变事件。但是,增加缓冲区大小是昂贵的,因为 它来自无法交换到磁盘的非分页内存,因此 使缓冲区尽可能小。要避免缓冲区溢出,请使用 NotifyFilter和IncludeSubdirectories属性用于筛选 不需要的更改通知
2>另外,您在创建的
fileSystemWatcher1\u中做了很多事情,这可能会导致缓冲区溢出,导致它错过一些事件…请改用线程池。我很好奇:虽然“创建”方法尚未完成,但不会检测到新创建的文件?我以为他们会排队?@Anirudh所以,理论上,即使我马上把它放到一个线程中,我也可能错过一个填充,对吗?如果您喜欢多个客户同时将文件放入一个位置。我猜您必须设置多个文件观察程序,并将检测到的文件操作排队(以及过滤双重或过程)@derape oops..我错了..我刚刚测试了它,即使你执行了线程,它也会引发事件。睡眠1分钟。但是缓冲区可能会溢出,一些事件可能会丢失missed@Anirudh感谢您的澄清,我想默认缓冲区对于大多数情况来说已经足够了。也许我会在我还有时间的时候检查有多少文件操作会导致filewatcher丢失文件…我不认为缓冲区大小是一个问题,一次只有一个文件。该文件是一个单独的图像,用当前时间“标记”并移动到另一个文件夹。当它工作时,操作会根据@Anirudh的回答接受一些注释:因为,您的事件处理程序代码正在忙于执行,可能是您的文件没有被注意到。你应该做的是提出建议,使用线程池,然后,_fileWatcher.Created+=(sender,e)=>YourOwnHandler(e.FullPath);对于这些“监视文件夹中可能被锁定的新文件并将其移动到其他地方”任务,我总是不使用FileSystemWatcher
,而是使用计时器定期扫描文件夹(例如每秒一次),收集文件名,然后尝试移动它们。当您不必与FileSystemWatcher
@christopherén:Read my exception series:的特性搏斗时,解决方案会变得更简单、更可靠。也许它可以帮助您更好地理解异常。