C# FileSystemWatcher,取消订阅事件
我在和4.0中的FileSystemWatcher鬼混。我觉得这很有用,但我陷入了一个循环。我试图监视ini的任何更改,并将其更改回正确的默认值(说来话长),但是,在新文件上复制更改事件会导致它陷入循环。。。有什么想法吗?我反复考虑删除并重新创建文件以避免触发已更改的事件,但这会导致程序出现另一系列问题,我宁愿避免。我还想象我可以改写文本,但这也带来了同样的问题。提前谢谢你的帮助C# FileSystemWatcher,取消订阅事件,c#,C#,我在和4.0中的FileSystemWatcher鬼混。我觉得这很有用,但我陷入了一个循环。我试图监视ini的任何更改,并将其更改回正确的默认值(说来话长),但是,在新文件上复制更改事件会导致它陷入循环。。。有什么想法吗?我反复考虑删除并重新创建文件以避免触发已更改的事件,但这会导致程序出现另一系列问题,我宁愿避免。我还想象我可以改写文本,但这也带来了同样的问题。提前谢谢你的帮助 static void Main() { Watch (@"\\NoFault2010\Lexis\Data\S
static void Main() { Watch (@"\\NoFault2010\Lexis\Data\Setup\", "tmconfig.ini", true); }
static void Watch (string path, string filter, bool includeSubDirs)
{
using (var watcher = new FileSystemWatcher (path, filter))
{
watcher.Changed += FileChanged;
watcher.EnableRaisingEvents = true;
Console.WriteLine("Do Not Close ... \n\nThis is a Temporary Configuration Manager for Time Matters ... \n\n\nI'm Listening ............");
Console.ReadLine();
}
}
static void FileChanged (object o, FileSystemEventArgs e)
{
string _right_stuff = @"\\NOFAULT2010\Lexis\Data\Templates\Programs\tmconfig.ini";
string _working = @"\\NOFAULT2010\Lexis\Data\Setup\tmconfig.ini";
System.Threading.Thread.Sleep(2000);
File.Copy(_right_stuff, _working, true);
Console.WriteLine("File {0} has been {1}", e.FullPath, e.ChangeType);
MAIL_IT("SQLMail@lcjlawfirm.com", "TM Master.INI has been altered", "Check the Master INI and Yell At Ecopy Guy " + e.ChangeType + e.FullPath);
}
如何取消订阅事件以避免进入此循环。您可以添加一个布尔值(同样是在类级别),用于跟踪更改是否由您引起,如果是,请立即退出FileChanged方法,即:
static bool inEdit;
static void FileChanged (object o, FileSystemEventArgs e)
{
if (inEdit)
return;
inEdit = true;
// Do processing
inEdit = false;
}
要在自己处理文件时临时禁用事件,请执行以下操作:
static void FileChanged (object o, FileSystemEventArgs e)
{
watcher.Changed -= FileChanged;
... correct the file here...
watcher.Changed += FileChanged;
}
或者,您可以使用guard变量检测可重入调用:
static bool reentrant = false;
static void FileChanged (object o, FileSystemEventArgs e)
{
if (reentrant)
return;
reentrant = true;
... correct the file here...
reentrant = false;
}
请注意,您还需要在该方法中执行异常处理,否则如果出现问题,您的文件监视程序可能会永久禁用。取消订阅很容易,因此我想知道这是否是问题所在:
watcher.Changed -= FileChanged
另外,我将创建一些对象作为观察者的SynchronizationObject。默认情况下,watcher会在新线程中引发事件,因此,如果在创建新线程后取消订阅,则可能会遇到问题
还注意到,FraseSistMeaveCurter可能会为你认为是单个事件的事件引发多个事件,并且可能影响程序的运行。
如果使观察者成为类变量而不是局部变量,那么您的文件更改方法应该能够访问它。那么你应该可以做一些类似的事情
static void FileChanged (object o, FileSystemEventArgs e)
{
watcher.EnableRaisingEvents = false;
// Edit the file here
watcher.EnableRaisingEvents = true;
}
我已经编写了一个依赖于filesystemwatcher的应用程序,而且有时候fsw处理程序会对文件进行更改。 我用两种方法来处理它——第一种是认为我的代码在更改文件时会非常快——所以我这么做了
fsw.EnableRaisingEvents = false;
//make my change
fsw.EnableRaisingEvents = true;
但是,如果您觉得其他文件可能在这段时间内发生更改,您可以记录更改的时间并将数据存储在某个位置
比如说,Dictionary mapFileNameTimeChanged…您可以在这里存储文件名…这样您就可以在处理程序中执行如下操作
fsw_Changed(object sender, FileSystemEventArgs e)
{
lock (m_mapFileNameChanged)
{
if (m_mapFileNameChanged.ContainsKey(e.FullPath))
{
FileInfo fileInfo = new FileInfo(e.FullPath);
if (fileInfo.LastAccessTime == m_mapFileNameChanged[e.FullPath]
{
return;//not been changed since you last did something with it....
}
}
else
{
m_mapFileNameChanged.Remove(e.FullPath);//discard this now..it has changed since you last looked at it...need to look at it again!
}
}
//do things in your event handler...
lock (m_mapFileNameChanged)
{
// copy or change the file here...
FileInfo fileInfo = new FileInfo(e.FullPath);
m_mapFileNameChanged[strFullPathToFile] = fileInfo.LastAccessTime;
}
}
-0.5:这里可能会有一场比赛,这将使比赛无法进行。如果在传递事件时出现延迟(例如,事件已排队),则更改事件将在FileChanged()退出后发布(并且inEdit已返回false)。