我写了一个FileSystemWatcher
为每个文件调用一次 pgm。但我的一些文件丢失了。我只用 10-11 个文件测试了代码。文件的删除会被正确记录,但创建不会被正确记录。某些文件未记录。我的 TASK 实施可能存在问题吗?
或者有什么问题吗Window Service
?
public static FileSystemWatcher m_Watcher;
static BlockingCollection<string> blockingCollection = new BlockingCollection<string>();
protected override void OnStart(string[] args)
{
current_directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
//XmlDocument xml = new XmlDocument();
try
{
strDir = ConfigurationManager.AppSettings["Directory"];
fileMask = ConfigurationManager.AppSettings["FileMask"];
strBatfile = ConfigurationManager.AppSettings["Batch"];
strlog = ConfigurationManager.AppSettings["Log"];
m_Watcher = new FileSystemWatcher();
m_Watcher.Filter = fileMask;
m_Watcher.Path = strDir + "\\";
m_Watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
m_Watcher.Created += new FileSystemEventHandler(OnCreated);
m_Watcher.Deleted += new FileSystemEventHandler(OnDeleated);
m_Watcher.Renamed += new RenamedEventHandler(OnRenamed);
m_Watcher.EnableRaisingEvents = true;
}
catch (Exception exception)
{
CustomException.Write(CustomException.CreateExceptionString(exception.ToString()));
}
}
public static void OnDeleated(object source, FileSystemEventArgs e)
{
try
{
Log.getLogger("File deleated- Filename :" + e.Name + " at timestamp : " + DateTime.Now.ToString(), strlog);
}
catch (Exception exception)
{
CustomException.Write(CustomException.CreateExceptionString(exception, e.Name));
}
}
private static void OnCreated(object source, FileSystemEventArgs e)
{
var exceptions = new ConcurrentQueue<Exception>();
try
{
Task.Factory.StartNew(() =>
{
try
{
blockingCollection.Add(e.Name.ToString());
}
catch (Exception)
{
throw;
}
});
Task.Factory.StartNew(() =>
{
try
{
foreach (string value in blockingCollection.GetConsumingEnumerable())
{
System.Diagnostics.Process.Start(Service1.strBatfile);
Log.getLogger("File Processed after executing batch: Filename ->:" + value + " " + "Batch File Executed- > " + Service1.strBatfile + " at timestamp : " + DateTime.Now.ToString(), Service1.strlog);
}
}
catch (Exception)
{
throw;
}
});
}
catch (AggregateException ae)
{
foreach (var ex in ae.InnerExceptions)
{
CustomException.Write(CustomException.CreateExceptionString(ex, e.Name));
}
}
finally
{
m_Watcher.EnableRaisingEvents = true;
}
}
您正在使用许多线程/任务的方式来清楚地了解代码是如何工作的。正如您所说,您只想一次只处理一个文件,您只需要一个在类的生命周期内存在的线程/任务(我假设是应用程序)。
如果我剥离您的代码以在每当将文件放入某个文件夹时一次处理一个文件,这可能是一种实现。
请注意我如何拥有一个ConcurrentQueue
以及读取该队列的一种方法。我也用这个方法WaitForExit https://msdn.microsoft.com/en-us/library/fb4aw7b8(v=vs.110).aspx在流程实例上防止运行多个流程。
static ConcurrentQueue<string> filenames = new ConcurrentQueue<string>();
static void QueueHandler()
{
bool run = true;
AppDomain.CurrentDomain.DomainUnload += (s, e) =>
{
run = false;
filenames.Enqueue("stop");
};
while(run)
{
string filename;
if (filenames.TryDequeue(out filename) && run)
{
var proc = new Process();
proc.StartInfo.FileName = filename;
proc.Start();
proc.WaitForExit(); // this blocks until the process ends....
}
}
}
现在我们需要一个将运行的任务/线程QueueHandler
和我们的FileSystemWatcher
:
protected override void OnStart(string[] args)
{
// have our queue reader method started
Task.Factory.StartNew(QueueHandler);
var fsw = new FileSystemWatcher();
fsw.Created += (o, e) =>
{
// add a file to the queue
filenames.Enqueue(e.FullPath);
// optionally add polling for missed files
// http://stackoverflow.com/questions/239988/filesystemwatcher-vs-polling-to-watch-for-file-changes
};
fsw.Path = ConfigurationManager.AppSettings["Directory"];
fsw.NotifyFilter = NotifyFilters.FileName;
fsw.Filter = ConfigurationManager.AppSettings["FileMask"];
fsw.EnableRaisingEvents = true;
}
此实现最多将使用三个线程:一个主线程,一个用于创建事件FileSystemWatcher
和一个用于QueueHandler
相反,如果您的示例代码中每次在 FileSystemWatcher 正在监视的文件夹中创建新文件时都会启动新任务
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)