1

エンドレスを開始するアプリケーションを設計しましたThread。これThreadは、SOAP-API を介して特定のデバイスからイベントを収集し、特定のイベントが発生したときにさまざまなメソッドを実行します。
これらすべてをサービスとして実行したいのですが、アプリケーションの設計方法がわかりません。

私の現在の計画は、サービスを提供することです。そのサービスは、情報を収集する「ポーラー」クラスのインスタンスを作成します。その後、「ポーラー」のポーリング機能を常時実行するスレッドが作成されます。「ポーラー」のインスタンスとスレッドをすべて作成してOnStart、サービス アプリケーションのイベントで実行する必要がありますか? OnStopまた、イベントでスレッドを停止する必要がありますか? それとももっと賢いデザインがあるでしょうか?

OnStartイベントは永遠に実行されるべきではないことを読んだので、これについてはわかりません。しかし、ここから呼び出すと永遠に実行されThreadますか?

これは私の最初のサービスアプリケーションであるため、助けてくれてありがとう:-)

4

1 に答える 1

5

「ポーラー」クラスは、作成したポーリング スレッドから使​​用されるため、いくつかの選択肢があります。おそらく、ポーラー クラス ctor でポーリング スレッドを作成することになるでしょう。スレッドがそれ以上のスコープを持つ理由はないようです。さらにデバイスが追加された場合は、ポーラー インスタンスをさらに作成するだけで済みます。

OnStart() で、ポーラー インスタンスを作成し (それ自体がポーラー スレッドを作成します)、戻り、'OnStart-Event を永久に実行しないでください' 条件を満たします。

OnStop() でスレッドを停止しますか? まず、スレッドを停止するための望ましい方法を試してください。まったくやろうとしないでください。サービス マネージャーまたはタスク マネージャーからシャットダウンしたときに、サービスは正常に実行され、すぐに停止しますか? その場合は、OnStop() またはポーラー クラス dtor でポーリング スレッドを明示的に停止しようとして、不必要な、または逆効果になる可能性のある作業を行わないでください。OnStop() を空のままにして、正常に動作するかどうかを確認してください。

サービス プロセスが OS によって強制終了される前にスレッドを終了する必要があることがわかった場合は、ポーラー スレッドをすぐに終了させるための巧妙な手段に訴える必要があるか、Thread.Interrupt() を使用して回避する必要があります。依存します..

ちょうど見るために、私はこれを試しました:

class poller
{
    public static void ThreadProc()
    {
        for (;;)
        {

            Thread.Sleep(0);
        }
    }
    Thread myThread;
    public poller(){
        myThread = new Thread(new ThreadStart(ThreadProc));
        myThread.Priority = ThreadPriority.BelowNormal;
        myThread.Start();
    }
};

class WindowsService : ServiceBase
{
    poller thisPoller;
    public WindowsService()
    {
        this.ServiceName = "My Windows Service";
        this.EventLog.Log = "Application";

        this.CanHandlePowerEvent = true;
        this.CanHandleSessionChangeEvent = true;
        this.CanPauseAndContinue = true;
        this.CanShutdown = true;
        this.CanStop = true;
    }
    protected override void OnStart(string[] args)
    {
        base.OnStart(args);
        thisPoller = new poller();
    }
    protected override void OnStop()
    {
        base.OnStop();
    }

いくつかのプロジェクト プロパティをいじり、適切なバージョンの installUtil を実行した後、正常にビルドおよびインストールされました。i7でCPU使用率が約17%の「プロセス」タブにサービスが表示されたため、スリープ(0)ループは明らかに機能していました。タスク マネージャー サービスで [サービスの停止] を選択すると、サービスの状態はすぐに [停止] になりましたが、プロセスが消えるまでに 20 秒ほどかかりました (?)。

もっと楽しむために、私は本当に箱を積み込みました。サービスを停止し、アンインストールして再構築しました:

protected override void OnStart(string[] args)
{
    base.OnStart(args);
    thisPoller = new poller();
    thisPoller = new poller();
    thisPoller = new poller();
    thisPoller = new poller();
    thisPoller = new poller();
    thisPoller = new poller();
    thisPoller = new poller();
    thisPoller = new poller();
}

再インストールして再起動すると、タスク マネージャーに到達する前に CPU ファンの回転数が上がるのが聞こえたので、動作していることがわかった. 案の定、8 コアすべてで 100% です。

8 つの CPU ループ スレッドでも、停止は問題ありませんでした。再び、ステータスはすぐに「停止」になり、プロセスは約 20 秒後に消えました。

スレッドが実行されないようにスリープ間隔を「1000000」に設定することも問題ではありませんでした-開始OK、停止OK。

于 2012-04-25T09:28:25.923 に答える