8

我正在考虑编写一个 Windows 服务,该服务将在用户指定的时间打开或关闭某些功能(使用我将提供的配置实用程序)。基本上,用户会指定 PC 进入“仅工作”模式的特定时间(阻止 Facebook 和其他分散注意力的网站),然后当这些时间结束时,PC 将返回正常模式。

我已经想出了几种创建“仅工作”模式的方法,但我正在努力解决的是如何知道何时进入和退出该模式。如果可以避免的话,我真的不想使用线程和计时器,因为这似乎会产生大量开销,所以我正在寻找的方法是:

  • 如果有某种 timeChanged() 事件要检查,则连接到 Windows API
  • 使用某种预建库在指定时间触发事件
  • 其他一些我没有想到的方法是优雅而美妙的

有谁知道做到这一点的最佳方法?

4

2 回答 2

9

我认为您可以使用您提到的Windows 服务很好地实现它。在我们的一个生产系统中,我们有一个以以下方式实现的 Windows 服务(根据要求提供不同的核心功能),该服务已经安全运行了近三年。

基本上,以下代码的目的是每次内部计时器(myTimer)唤醒时服务执行特定的方法。

下面是一个基本的实现。在这个例子中,你的核心功能应该放在方法EvalutateChangeConditions中,它应该每 60 秒执行一次。我还将为您的管理客户提供一种公共方法,以了解当前的“工作模式”。

public partial class MyService : ServiceBase
{
    private System.Threading.Thread myWorkingThread;
    private System.Timers.Timer myTimer = new System.Timers.Timer();

    // [...] Constructor, etc

    protected override void OnStart(string[] args)
    {
        // Do other initialization stuff...

        // Create the thread and tell it what is to be executed.
        myWorkingThread = new System.Threading.Thread(PrepareTask);

        // Start the thread.
        myWorkingThread.Start();
    }

    // Prepares the timer, sets the execution interval and starts it.
    private void PrepareTask()
    {
        // Set the appropiate handling method.
        myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);

        // Set the interval time in millis. E.g.: each 60 secs.
        myTimer.Interval = 60000;

        // Start the timer
        myTimer.Start();

        // Suspend the thread until it is finalised at the end of the life of this win-service.
        System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
    }

    void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        // Get the date and time and check it agains the previous variable value to know if
        // the time to change the "Mode" has come.
        // If does, do change the mode...
        EvalutateChangeConditions();
    }

    // Core method. Get the current time, and evaluate if it is time to change
    void EvalutateChangeConditions()
    {
        // Retrieve the config., might be from db? config file? and
        // set mode accordingly.
    }

    protected override void OnStop()
    {
        // Cleaning stuff...
    }
}
于 2012-05-14T08:47:34.507 回答
3

如果 Windows 任务计划程序没有理由不适合您,我建议您使用它。

如果您不想使用任务调度程序,我将有一个简单的循环来检查任何即将发生的事件(锁定/解锁站点)并执行任何到期的事件。如果没有事件发生,请长时间休眠(Thread.Sleep())。
我没有研究过长时间睡眠的任何副作用,但是一分钟的睡眠时间不应该消耗太多资源。如果它不是服务,我可能会进行终止检查,但我认为服务并不意味着终止。

于 2012-05-13T23:11:19.107 回答