我创建了一个 C# Windows 服务应用程序,该应用程序启动 FileSystemWatcher
来监视目录中文件的创建。找到文件后,我实例化一个自定义类,该类解析文件 (CSV) 并使用其内容调用 Web 服务。该服务在某种程度上是异步的,并返回一个唯一的编号,必须使用该编号进行后续调用以检查其进度。在我的流程类中,我创建了一个计时器来不断检查作业是否完成。当我完成后,我正在处置
并关闭
我的计时器,但我只是想确保我的类将被垃圾收集,并且不会有任何内存泄漏.
代码如下所示(为简洁起见,进行了删减):
我的主要服务类别:
protected override void OnStart(string[] args)
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = "path";
watcher.Filter = "file";
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.EnableRaisingEvents = true;
}
static void watcher_Created(object sender, FileSystemEventArgs e)
{
FileProcessor p = new FileProcessor();
p.Process(e.FullPath);
//Will this instance of p stick around until the timer within it is finished?
}
FileProcessor.cs
class FileProcessor
{
private System.Timers.Timer timer = new System.Timers.Timer();
private string id;
public FileProcessor()
{
timer.Elapsed += new ElapsedEventHandler(OnTimer);
timer.Enabled = false;
timer.AutoReset = true;
}
public void Process(string filename)
{
//Read file <snipped>
//Call web service and get id
id = CallWebService();
//Create a timer for 10 seconds and start it
timer.Interval = 10000;
timer.Enabled = true;
}
private bool IsFinished(string id)
{
//Call web service to see if job is finished, true if finished
//<snipped>
}
private void ProcessResults()
{
//Job is finished, process results
//Call cleanup method to dispose of timer
Cleanup();
}
private void OnTimer(object source, ElapsedEventArgs e)
{
if (!IsFinished(id))
{
//Keep timer running, check result again next timer event
return;
}
else
{
//Stop timer
timer.Stop();
//Process Results
ProcessResults(response);
}
}
private void Cleanup()
{
timer.Close();
timer.Dispose();
}
}
我的问题是我的“p”实例应该保留(而不是被GC)直到我的计时器被销毁吗?它会被摧毁吗?我的 FileProcessor 类是否需要实现 IDisposable 以便我可以将其包装在 using block 中?我并不担心这是单线程的,因为我只希望它每天处理一个文件,并且该过程完成并返回以监视要创建的下一个文件的时间不应超过 10 分钟。
最佳答案
您走在正确的道路上。 FileSystemWatcher实现Component类,这要求您在使用后将其丢弃。既然是这种情况,正确的方法是让您的 FileProcessor 类按照您的建议实现 IDisposable。
由于FileProcessor对象将长期存在,因此您将无法使用 using陈述。这是因为该对象会在完成其工作之前尝试将其释放。
在这种情况下,我将在 FileProcessor 上实现一个事件,以在处理完成时通知使用者。完成后,我将调用 FileProcessor 对象上的 Dispose 方法。 Dispose 方法应该执行该对象所需的所有清理 - IE:计时器、观察器等。
供您引用,this is a good article其中列出了何时以及如何使用 IDisposable 接口(interface)的一些准则。另外,作为一个好的实践,您需要将消费者中的调用包装在 try/catch block 中 - 您需要确保无论发生什么情况,您都会尝试释放资源。
关于c# - 带有 FileSystemWatcher 和 Timer 的 Windows 服务 - 确保所有内容都得到处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7740421/