【问题标题】:DispatchTimer not firing in serviceDispatcherTimer 未在服务中触发
【发布时间】:2018-07-20 22:23:32
【问题描述】:

我有一个用 C# 实现的 Windows 服务。该服务监视许多目录以查找要保存的文件。然而,为了让它更健壮,我试图让它在一段时间后检查文件夹。

称为 Watcher 的内部类初始化 fileSystemWatcher 和 DispatchTimer。

public class Watcher
{
    FileSystemWatcher fileSystemWatcher = null;

    public delegate void TimerInvokedHandler(object sender);
    public event TimerInvokedHandler TimerInvoked;

    public DispatcherTimer Timer { get; set; }

    public int TimerMinutes { get; set; }

    public Watcher()
    {

    }

    public Watcher(String directory, String filter, String dap)
    {
        this.DAP            = dap;
        this.Directory      = directory;
        this.Filter         = filter;
    }

    public Boolean EnableRaisingTimerEvents
    {
        get { return this.Timer.IsEnabled;  }
        set
        {
            this.Timer.IsEnabled = value;
            if (value)
            {
                this.Timer.Start();
                Log("Timer Started");
            }
            else
            {
                this.Timer.Stop();
                Log("Timer Stopped");
            }

        }
    }

    private void Timer_Tick(object sender, EventArgs e)
    {
        StopWatch();
        TimerInvoked?.Invoke(sender);
    }

    public void StartWatch()
    {
        if (fileSystemWatcher == null)
        {
            fileSystemWatcher = new FileSystemWatcher();
            fileSystemWatcher.Filter = Filter;
            fileSystemWatcher.Path = Directory;

            fileSystemWatcher.Created += FileSystemWatcher_Created;
            fileSystemWatcher.Renamed += FileSystemWatcher_Renamed;

            fileSystemWatcher.Error += FileSystemWatcher_Error;
        } 

        if (this.Timer == null)
        {
            Log("Initialising Timer");

            this.Timer = new DispatcherTimer();
            this.Timer.Interval = new TimeSpan(0, this.TimerMinutes, 0);
            this.Timer.Tick += Timer_Tick;
        }

        this.EnableRaisingFileSystemsEvents = true;
        this.EnableRaisingTimerEvents = true;

        Log(String.Format("Watching Directory {0}", Directory));
    }

    // stops timer and file system events
    public void StopWatch()
    {
        if (fileSystemWatcher != null) 
            EnableRaisingFileSystemsEvents = false;

        if (Timer != null)
        {
            EnableRaisingTimerEvents = false;
        }

        Log(String.Format("Watching {0} Switched Off", this.Directory));
    }


    private void Log ( String Message )
    {
        LogEvent?.Invoke(this, Message);
    }

}

外部类创建这些观察者的列表,这是基于 ServiceBase,因为它是一个服务,因此只有在 Windows 服务管理器中停止时才结束

                foreach (nhs_acquisition_profile pfl in p)
                {
                    Watcher w = null;
                    String filePattern = String.Empty;

                    try
                    {

                        profileWatcherLog.WriteEntry(String.Format("Attempting to set-up watcher on {0} for DAP {1}",pfl.dap_file_location,pfl.dap_name));

                        if (pfl.dap_acquisition_method_loca.ToLower() == "xml") w = new Watcher(pfl.dap_file_location, "*.xml", pfl.dap_name);
                        else w = new Watcher(pfl.dap_file_location, "*.*", pfl.dap_name);

                        profileWatcherLog.WriteEntry("Initialising Event Handlers");
                        // initialise event handlers
                        w.FileCreated   += W_FileCreated;
                        w.FileRenamed   += W_FileRenamed;
                        w.TimerInvoked  += W_TimerInvoked;
                        w.LogEvent      += W_LogEvent;
                        profileWatcherLog.WriteEntry("Event Handlers initialised");

                        // dispatch timer

                        w.TimerMinutes = Convert.ToInt32(Properties.Settings.Default.TimerDelay);

                        w.StartWatch();

                        profileWatcherLog.WriteEntry("Watch started....Adding to Watcher List");

                        // add the watcher to the list of watchers
                        FileWatcherList.Add(w);

                        profileWatcherLog.WriteEntry("Added to list of file watchers");

                        profileWatcherLog.WriteEntry(String.Format("Watching {0} for files matching *.* for DAP {1}",pfl.dap_file_location,pfl.dap_name));
                    }
                    catch
                    {
                        throw;
                    }
                }

变量 FileWatcherList 是构成整个服务的 ProfileWatcher 类的一个字段。

我发现 DispatchTimer Tick 事件永远不会发生。我有理由确定这不是 DispatchTimer 在 Tick 之前被处置的实例,但看不出它为什么没有触发。

【问题讨论】:

  • 你的程序有 WPF UI 吗? DispatcherTimer 仅在有 UI Dispatcher 时才有效。您可能应该改用 System.Threading.Timer。
  • Dmitri Baliev - 可能就是这样。这是一项服务,所以它没有接口,更不用说用 WPF 编写的了!

标签: c# service


【解决方案1】:

Dmitri 是正确的,我应该使用 Timer 而不是 DispatchTimer。一旦我搬到那里,它就可以正常工作了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-29
    • 2017-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-23
    相关资源
    最近更新 更多