【问题标题】:Windows Service constantly looking for filesWindows 服务不断寻找文件
【发布时间】:2016-12-23 16:21:33
【问题描述】:

对不起,如果这是一个愚蠢的问题,但我对 Windows 服务还很陌生,我想确保我了解处理这种情况的正确方法。

我有一个用于监视文件的 Windows 服务,如果这些文件存在,它会处理它们。我正在查看一个旧开发人员的代码,如果文件不存在,他们会使用 Thread.Sleep() 。我知道这是一种不好的做法,并且亲眼目睹了这会锁定服务。

这是我的逻辑的简化示例:

private Task _processFilesTask;
private CancellationTokenSource _cancellationTokenSource;

public Start()
{
   _cancellationTokenSource = new CancellationTokenSource();
   _processFilesTask = Task.Run(() => DoWorkAsync(_cancellationTokenSource.Token))
}

public async Task DoWorkAsync(CancellationToken token)
{
   while(!token.IsCancellationRequested)
   {
      ProcessFiles();
      //await Task.Delay(10000);
   }
}

public Stop()
{
   _cancellationTokenSource.Cancel();
   _processFilesTask.Wait();
}

private void ProcessFiles()
{
  FileInfo xmlFile = new DirectoryInfo(Configs.Xml_Input_Path).GetFiles("*.xml").OrderBy(p => p.CreationTime).FirstOrDefault();
  if(xmlFile != null)
    {
      //read xml
      //write contents to db
      //move document specified in xml to another file location
      //delete xml
    }
}

我的第一个问题:是否需要任何延迟或暂停?如果我没有任何暂停,那么此服务将不断在远程服务器上查找文件。这是我必须担心的事情,还是一个相当轻量级的过程?

第二个问题:如果暂停而不是不断访问此服务器会更好,这是更好的方法还是您会推荐什么?

public  async Task DoWorkAsync(CancellationToken token)
{
   while(!token.IsCancellationRequested)
   {
      ProcessFiles();
      await Task.Delay(TimeSpan.FromMilliseconds(10000), token).ContinueWith(_processFilesTask=> { });
   }
}

感谢您的帮助!

【问题讨论】:

  • 你还没有展示它是如何查找文件的,所以我们不能说它是否是轻量级的。但通常最好有延迟,否则可能会出现繁忙的循环,只会吸走所有资源。是的,Task.Delay 就是你想要使用的
  • 糟糕,我更新了我的代码。在此示例中,if 尝试查找按创建时间排序的 .xml 文件并检查它们是否存在。一天的 75% 时间,此目录中将没有文件。使用延迟而不是不断执行 .GetFiles() 方法会更好吗?
  • 你肯定想要一些暂停。不断地探测服务器是对 CPU 和网络资源的巨大浪费。您是否考虑过只使用Timer?还有FileSystemWatcher 方法,但我发现它在监控远程文件夹/文件时不太可靠。
  • 我就是这么想的。我查看了 Timers 并阅读了一些关于 FileSystemWatcher 的信息,但人们也说了同样的话。我以为我读到计时器的缺点是每次计时器准备好时它都会启动一个新线程,即使前一个线程仍在处理,这是正确的吗?我真的只需要一个线程来运行所以也许延迟是要走的路

标签: c# windows asynchronous service task


【解决方案1】:

您可以使用计时器来检查所需的文件和文件夹。这是大纲。

  1. 在您的服务类中添加 Timer(继承 ServiceBase 类)

    私有 System.Timers.Timer myTimer;

  2. 在 OnStart 方法中初始化计时器。

    protected override void OnStart(string[] args)
    {
        // Set the Interval to 1 seconds (1000 milliseconds).
        myTimer = new System.Timers.Timer(1000);
    
        // Hook up the Elapsed event for the timer.
        myTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
    
        myTimer.Enabled = true;
    
    }
    
  3. 定义经过的事件处理程序。

    private void OnTimedEvent(object source, ElapsedEventArgs e)
    {
        //Write your file handling logic here.
        //Service will execute this code after every one second interval
        //as set in OnStart method.
    }
    

【讨论】:

  • 在这里使用计时器有什么好处?
  • 使用定时事件服务将在指定的时间间隔而不是所有时间检查文件。
  • 但是像 OP 那样延迟有什么好处呢?
猜你喜欢
  • 2011-03-06
  • 1970-01-01
  • 2011-06-19
  • 1970-01-01
  • 1970-01-01
  • 2021-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多