我有一个用 C# 编写的 Windows 服务。在幕后,它是一个 FileSystemWatcher。 FSW 查找新文件并相应地处理它们。当我的服务启动时,它还需要处理现有文件。当我通过控制台应用程序执行此操作时,一切都按预期进行。
但是,当我尝试将这一切包装在 Win 服务中时,我遇到的第一个问题是 Win 服务无法启动。超时是因为即使最初有很多文件要处理,处理时间也太长。
这是我的“观看”类(class)的部分代码:
public WatcherService()
{
_log.Debug("WatcherService instantiated.");
_watcher = new FileSystemWatcher { Path = AppConfig.MonitorFolder, IncludeSubdirectories = true };
// we want the watching to start BEFORE we process existing files
// because if we do it the other way, a file might get missed
_watcher.Created += File_OnChanged;
}
public void StartWatching()
{
_log.Debug("WatcherService started.");
// this kicks off the watching
_watcher.EnableRaisingEvents = true;
// process existing files
ProcessExistingFiles(AppConfig.MonitorFolder);
}
我的解决方法是启动 FSW“观察”并在单独的异步线程上处理初始文件,就像这样(在我的 Windows 服务代码中):
protected override void OnStart(string[] args)
{
_log.Debug("LoggingService starting.");
// kick off the watcher on another thread so that the OnStart() returns faster;
// otherwise it will hang if there are a lot of files that need to be processed immediately
Task.Factory.StartNew(() => _watcher.StartWatching()).ContinueWith(t =>
{
if (t.Status == TaskStatus.Faulted)
{
_log.Error("Logging service failed to start.", t.Exception.InnerException ?? t.Exception);
}
});
}
如果我没有在 Task.Factory.StartNew() 中包装“StartWatching”方法,OnStart() 就会超时,这是可以理解的。但现在似乎我的 StartWatching() 方法从未被调用过。我在日志中看到“LoggingService starting”,但看不到“WatcherService started”。 (编辑:仅供引用,我也尝试过 Task.Run(),但无济于事。)
那怎么办?我确信我要么不明白 StartNew() 在做什么,要么有更好的方法来完成我想要完成的事情。
想法?
谢谢!
最佳答案
您可以完全避免线程化。只需在 OnStart()
方法中进行基本设置。该设置的一部分是设置一个定时器,使其在一两秒内响起。该计时器可以在当前线程上运行,但会在服务空闲后发生。
这将解决问题,并且编写线程安全代码更容易。
关于c# - 快速启动简单的 C# FileSystemWatcher Windows 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23792241/