プログラムを繰り返し(たとえば2分ごとに)実行するためのWindowsサービスとスケジュールされたタスクの短所と長所は何ですか?
11 に答える
アップデート:
私の最初の答えからほぼ4年後、この答えは非常に時代遅れです。TopShelfが登場して以来、Windowsサービスの開発は容易になりました。ここで、フェイルオーバーをサポートする方法を理解する必要があります...
元の回答:
私は実際にはWindowsスケジューラのファンではありません。@moodforallが上記で指摘しているように、ユーザーのパスワードを指定する必要があります。これは、誰かがそのユーザーのパスワードを変更したときに楽しいものです。
Windowsスケジューラのもう1つの大きな問題は、バックグラウンドプロセスとしてではなく、インタラクティブに実行されることです。RDPセッション中に15個のMS-DOSウィンドウが20分ごとにポップアップすると、代わりにWindowsサービスとしてインストールしなかった自分自身を蹴ります。
どちらを選択しても、処理コードをコンソールアプリやWindowsサービスとは別のコンポーネントに分離することをお勧めします。次に、コンソールアプリケーションからワーカープロセスを呼び出してWindowsスケジューラにフックするか、Windowsサービスを使用するかを選択できます。
Windowsサービスのスケジュール設定は面白くないことがわかります。かなり一般的なシナリオは、定期的に実行したい長時間実行プロセスがある場合です。ただし、キューを処理している場合は、同じワーカーの2つのインスタンスが同じキューを処理することは実際には望ましくありません。したがって、タイマーを管理して、長時間実行されているプロセスが割り当てられたタイマー間隔より長く実行されている場合、既存のプロセスが終了するまでタイマーが再開されないようにする必要があります。
それをすべて書いた後、なぜ私はThread.Sleepを使用しなかったのでしょうか。これにより、現在のスレッドが終了するまで実行を継続し、一時停止間隔が開始され、スレッドがスリープ状態になり、必要な時間が経過すると再び開始されます。きちんとした!
次に、インターネット上のすべてのアドバイスを読み、多くの専門家が、それが本当に悪いプログラミング慣行である方法を教えてくれます。
だからあなたは頭をかいて、自分で考えます、WTF、保留中のチェックアウトを元に戻す->はい、確かに->今日のすべての作業を元に戻す.....くそー、くそー、くそー....
しかし、誰もがそれががらくただと思っていても、私はこのパターンが好きです:
シングルスレッドアプローチのOnStartメソッド。
protected override void OnStart (string args) { // Create worker thread; this will invoke the WorkerFunction // when we start it. // Since we use a separate worker thread, the main service // thread will return quickly, telling Windows that service has started ThreadStart st = new ThreadStart(WorkerFunction); workerThread = new Thread(st); // set flag to indicate worker thread is active serviceStarted = true; // start the thread workerThread.Start(); }
このコードは別のスレッドをインスタンス化し、ワーカー関数をそれにアタッチします。次に、スレッドを開始し、OnStartイベントを完了させて、Windowsがサービスがハングしていると見なさないようにします。
シングルスレッドアプローチのワーカーメソッド。
/// <summary> /// This function will do all the work /// Once it is done with its tasks, it will be suspended for some time; /// it will continue to repeat this until the service is stopped /// </summary> private void WorkerFunction() { // start an endless loop; loop will abort only when "serviceStarted" // flag = false while (serviceStarted) { // do something // exception handling omitted here for simplicity EventLog.WriteEntry("Service working", System.Diagnostics.EventLogEntryType.Information); // yield if (serviceStarted) { Thread.Sleep(new TimeSpan(0, interval, 0)); } } // time to end the thread Thread.CurrentThread.Abort(); }
シングルスレッドアプローチのOnStopメソッド。
protected override void OnStop() { // flag to tell the worker process to stop serviceStarted = false; // give it a little time to finish any pending work workerThread.Join(new TimeSpan(0,2,0)); }
ソース:http ://tutorials.csharp-online.net/Creating_a_.NET_Windows_Service%E2%80%94Alternative_1%3a_Use_a_Separate_Thread (デッドリンク)
私は何年もの間このような多くのWindowsサービスを実行してきました、そしてそれは私のために働きます。私はまだ人々が同意する推奨パターンを見ていません。自分に合ったことをしてください。
ここでいくつかの誤報。Windows スケジューラは、ウィンドウがポップアップせず、パスワードも必要なく、バックグラウンドでタスクを完全に実行できます。NT AUTHORITY\SYSTEM アカウントで実行します。この schtasks スイッチを使用します。
/ru システム
ただし、ネットワーク リソースにアクセスするためのベスト プラクティスは、別の無期限パスワード ポリシーを持つサービス アカウントです。
編集
OS とタスク自体の要件によっては、Localsystem よりも権限の低いアカウントをオプションで使用できる場合があり/ru
ます。
細かいマニュアルから、
/RU username
A value that specifies the user context under which the task runs.
For the system account, valid values are "", "NT AUTHORITY\SYSTEM", or "SYSTEM".
For Task Scheduler 2.0 tasks, "NT AUTHORITY\LOCALSERVICE", and
"NT AUTHORITY\NETWORKSERVICE" are also valid values.
タスク スケジューラ 2.0は、Vista および Server 2008 から利用できます。
XP および Server 2003 では、system
が唯一のオプションです。
.NET 開発では、通常、コンソール アプリケーションを開発することから始めます。このアプリケーションは実行され、すべての出力をコンソール ウィンドウに記録します。ただし、これはコマンド引数で実行された場合のコンソール アプリケーションのみ/console
です。このパラメーターを指定せずに実行すると、Windows サービスとして機能し、独自のカスタム コード スケジュール タイマーで実行され続けます。
私の考えでは、Windows サービスは通常、長時間実行されるアプリケーションではなく、他のアプリケーションを管理するために使用されます。または .. SQL Server、BizTalk、RPC 接続、IIS などの重いアプリケーションを継続的に実行しています (IIS は技術的に他のプロセスに作業をオフロードしますが)。
個人的には、ファイルのコピー/同期、メールの一括送信、ファイルの削除またはアーカイブ、データの修正 (他の回避策が利用できない場合) などの反復的なメンテナンス タスクやアプリケーションについては、ウィンドウ サービスよりもスケジュールされたタスクを好みます。
あるプロジェクトで、私は 8 つまたは 9 つの Windows サービスの開発に携わってきましたが、これらはメモリ内に留まり、アイドル状態で、インスタンスごとに 20MB 以上のメモリを消費します。スケジュールされたタスクは仕事をし、すぐにメモリを解放します。
アプリの起動と終了のオーバーヘッドはどれくらいですか?2分ごとはかなり頻繁です。サービスを使用すると、アプリケーションを頻繁に実行するよりもシステムをスムーズに実行できる可能性があります。
どちらのソリューションも、ユーザーがログインしていないときにプログラムを実行できるため、違いはありません。ただし、サービスの作成は通常のデスクトップアプリよりも多少複雑ですが、TCP / IP、名前付きパイプなどを介してサービスアプリと通信する別のGUIクライアントが必要になる場合があります。
ユーザーの視点から、どちらが制御しやすいのだろうか。サービスとスケジュールされたタスクはどちらも、ほとんどの技術者以外のユーザーにとってはほとんど手の届かないものです。つまり、サービスが存在することに気付かず、構成/停止/再スケジュールなどが可能です。
Windowsサービスには、だれもログインする必要はありません。Windowsには、サービスの結果を停止、開始、およびログに記録する機能があります。
スケジュールされたタスクでは、Windowsサービスの作成方法を学ぶ必要はありません。
- 適切なアクセス許可を使用して、Windowsサービスをセットアップおよびロックダウンする方が簡単です。
- サービスはより「目に見える」ものであり、誰もが(つまり技術者)どこを見ればよいかを知っていることを意味します。
なぜ両方を提供しないのですか?
過去に、「コア」ビットをライブラリに入れ、Whatever.GoGoGo() への呼び出しをサービスとコンソール アプリの両方にラップしました。
2 分ごとに発射している何かでは、オッズはまともですが、あまり機能していません (たとえば、「ping」タイプの機能のみ)。ラッパーには、単一のメソッド呼び出しといくつかのログを含める必要はありません。