8

ユーザーが指定した時間に特定の機能をオンまたはオフにするWindowsサービスを作成することを考えています(提供する構成ユーティリティを使用)。基本的に、ユーザーは、PC が「仕事専用」モード (Facebook やその他の気を散らすサイトをブロックする) になる特定の時間を指定し、その時間になると、PC は通常モードに戻ります。

「仕事専用」モードを作成する方法はいくつか考え出しましたが、苦労しているのは、いつそのモードに出入りするかを知る方法です。回避できるのであれば、スレッドとタイマーを実際に使用したくありません。それは、非常に多くのオーバーヘッドが発生するように思われるためです。したがって、私が探しているのは、次のいずれかの方法です。

  • チェックする何らかの種類の timeChanged() イベントがある場合は、Windows API にフックします。
  • 指定された時間にイベントを発生させるために、ある種のビルド済みライブラリを使用する
  • 私が思いつかなかった他の方法はエレガントで素晴らしいです

これを行う最良の方法を知っている人はいますか?

4

2 に答える 2

9

あなたが言ったように、 Windowsサービスでそれをうまく達成できると思います。私たちの製品システムの 1 つで、以下の方法で実装された Windows サービス (要求されたものとは異なるコア機能) があり、現在ほぼ 3 年間安全に実行されています。

myTimer基本的に、次のコードの目的は、内部タイマー ( ) が起動するたびにサービスが特定のメソッドを実行することです。

以下は基本的な実装です。この例では、コア機能を method に配置する必要があります。これ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() )。
長い睡眠の副作用については調べていませんが、1 分間の睡眠時間はリソースをあまり消費しないはずです。それがサービスではない場合、おそらく終了チェックを入れますが、サービスは終了することを意図していないと思います。

于 2012-05-13T23:11:19.107 に答える