Windowsサービスとスケジュールされたタスク


115

Windowsサービスと、プログラムを繰り返し実行するためのスケジュールされたタスク(たとえば、2分ごと)の短所と長所は何ですか。

回答:


51

更新:

私の元の回答からほぼ4年後、この回答は非常に古くなっています。TopShelfが登場して以来、Windowsサービスの開発は簡単になりました。次に、フェイルオーバーをサポートする方法を理解する必要があります...

元の回答:

私は本当にWindowsスケジューラのファンではありません。@moodforallが上で指摘したように、ユーザーのパスワードを提供する必要があります。これは、誰かがそのユーザーのパスワードを変更したときに楽しいことです。

Windowsスケジューラのもう1つの大きな問題は、バックグラウンドプロセスとしてではなく、対話的に実行されることです。RDPセッション中に20分ごとに15個のMS-DOSウィンドウがポップアップ表示されると、代わりにWindowsサービスとしてインストールされなかった自分を蹴るでしょう。

何を選択しても、処理コードをコンソールアプリやWindowsサービスとは異なるコンポーネントに分離することをお勧めします。次に、コンソールアプリケーションからワーカープロセスを呼び出してWindowsスケジューラにフックするか、Windowsサービスを使用するかを選択できます。

Windowsサービスのスケジュール設定は面白くないことがわかります。かなり一般的なシナリオは、定期的に実行したい長時間実行プロセスがあるというものです。ただし、キューを処理している場合は、同じワーカーの2つのインスタンスが同じキューを処理することは望ましくありません。したがって、タイマーを管理する必要があります。実行時間の長いプロセスが割り当てられたタイマー間隔よりも長く実行されているかどうかを確認するには、既存のプロセスが終了するまで、再び起動しないようにします。

それをすべて書いた後、なぜ私はThread.Sleepだけを使用しなかったのでしょうか。これにより、現在のスレッドが終了するまで実行を続け、その後、一時停止間隔が開始され、スレッドがスリープ状態になり、必要な時間後に再び開始されます。きちんと!

次に、インターネット上のすべてのアドバイスを読んで、多くの専門家がプログラミングのやり方が本当に悪いことを説明します。

http://msmvps.com/blogs/peterritchie/archive/2007/04/26/thread-sleep-is-a-sign-of-a-poorly-designed-program.aspx

だから、あなたは頭を悩まして、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 (Dead Link)

私はこのようなWindowsサービスを何年も実行してきましたが、私にとってはうまくいきました。私はまだ人々が同意する推奨パターンを見ていません。ちょうどあなたのために働くことをしてください。


2
実際に、独自のサービスアカウントを使用してサービスを実行したい場合があります。すべてはあなたがそれはおそらく必要がないことをあなたのアプリへのアクセス権を付与されているサービスやNETWORKSERVICEを実行している場合(それは1つだけでなく、サーバーのセキュリティが、ネットワーク全体を危険にさらすことができます。)
マシュー白く塗った

1
確かに。私は他に言ったとは思わないのですか?
レベッカ

4
あなたは最初の段落でそれ以外のことを暗示しています ビルトインアカウントを使用していない場合は、タスクスケジューラと同じサービスにユーザーのパスワードが必要です。
Nick Cox

1
@MatthewWhited NT AUTHORITY\NetworkServiceは、権限が制限されたアカウントです。
Ian Boyd 2013年

1
@IanBoydには、他のアプリケーションに関連するNetworkServiceに割り当てられた権限が含まれます。
マシューホワイト2013年

16

ここにいくつかの誤報があります。Windowsスケジューラは、ウィンドウがポップアップすることなく、パスワードを必要とせずに、バックグラウンドでタスクを完全に実行できます。NT AUTHORITY \ SYSTEMアカウントで実行します。このschtasksスイッチを使用します。

/ ruシステム

しかし、はい、ネットワークリソースにアクセスするためのベストプラクティスは、個別の有効期限なしのパスワードポリシーを持つサービスアカウントです。

編集

OSとタスク自体の要件によっては、/ruオプションを使用して、Localsystemよりも特権の少ないアカウントを使用できる場合があります。

ファインマニュアルより

/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が唯一のオプションです。


2
実行してくださいLocal Service(別名NT AUTHORITY\LocalServiceではなく)LocalSystem(別名.\LocalSystem)。前者には制限付きの権限がありますが、後者は管理者です
Ian Boyd

1
はい追加のアカウントLocalServiceNetworkServiceで利用できるschtasks以降V2 Vistaおよび可能であれば優先されなければなりません。当時、これschtasksはXPとServer 2003 Systemの古いバージョンのマニュアルtechnet.microsoft.com/en-us/library/bb490996.aspxの
Amit Naidu

XPでは、スケジュールされたタスクをSYSTEMとして実行できません。頑張ってください。これはうまく要約しています:cwl.cc/2011/12/run-scheduled-task-as-system.html
Pupsik

11

アプリの起動と終了のオーバーヘッドは何ですか?2分ごとがかなり頻繁です。サービスを使用すると、アプリケーションをそれほど頻繁に実行するよりもシステムをスムーズに実行できます。

どちらのソリューションでも、ユーザーがログインしていないときにプログラムを実行できるため、違いはありません。ただし、サービスの記述は通常のデスクトップアプリよりもやや複雑です。TCP/ IP、名前付きパイプなどを介してサービスアプリと通信する別のGUIクライアントが必要になる場合があります。

ユーザーの視点から、どちらが制御しやすいのかと思います。ほとんどの非技術ユーザーにとって、サービスとスケジュールされたタスクの両方はほとんど手の届かないところにあります。つまり、サービスが存在していることに気づかず、構成/停止/再スケジュールなどが可能です。


10

.NET開発では、通常、すべてのログ出力をコンソールウィンドウに実行するコンソールアプリケーションを開発することから始めます。ただし、コマンド引数を指定して実行した場合、これはコンソールアプリケーションにすぎません/console。このパラメーターなしで実行すると、Windowsサービスとして機能します。これは、独自にコード化した独自のスケジュールされたタイマーで実行を継続します。

私の考えでは、Windowsサービスは通常、長時間実行されるアプリケーションではなく、他のアプリケーションを管理するために使用されます。または..それらは、SQL Server、BizTalk、RPC接続、IIS(IISは技術的に他のプロセスへの負荷を軽減しますが)などの継続的に実行されるヘビー級アプリケーションです。

個人的には、ファイルサービスのコピー/同期、メールの一括送信、ファイルの削除またはアーカイブ、データの修正(他の回避策が利用できない場合)などの定期的なメンテナンスタスクやアプリケーションでは、ウィンドウサービスよりもスケジュールされたタスクを優先します。

1つのプロジェクトでは、8または9のWindowsサービスの開発に携わっていましたが、これらはメモリ内で待機し、インスタンスごとに20MB以上のメモリを消費しています。スケジュールされたタスクはビジネスを行い、メモリをすぐに解放します。


8

「サーブ」という言葉は「サーブ」と共通の何かを共有しています。それは常に実行されていると予想され、「サーブ」します。タスクはタスクです。

ロールプレイ。私が別のオペレーティングシステム、アプリケーション、またはデバイスであり、サービスを呼び出した場合、サービスが実行中であることを期待し、応答を期待します。私(os、app、dev)が分離されたタスクを実行するだけでよい場合は、タスクを実行しますが、通信(おそらく双方向通信)が必要な場合は、サービスが必要です。これは、2つの情報をやり取りする最も効果的な方法、または1つのタスクを実行したい1つの方法に関係しています。

次に、スケジューリングの側面があります。特定の時間に何かを実行したい場合は、スケジュールします。いつ必要になるかわからない場合、または「オンザフライ」で必要な場合は、サービスをご利用ください。

これは人間の相互作用や他の人との働き方と非常によく似ているため、私の応答は本質的に哲学的です。コミュニケーションの技術を理解し、エンティティがその役割を理解するほど、この決定は容易になります。

すべての哲学は別として、あなたが「迅速にプロトタイピング」しているときは、私のIT部門がよく行うように、やりがいを持たせるために必要なことは何でもします。プロトタイピングと概念実証のものが途絶えたら、通常は初期の計画と発見において、長期的な持続可能性にとってより信頼できるものを決定する必要があります。

結局のところ、結論は多くの要因に大きく依存していますが、うまくいけば、混乱の代わりに洞察が得られたと思います。


4

Windowsサービスには誰もログインする必要はありません。Windowsには、サービスの結果を停止、開始、および記録する機能があります。

スケジュールされたタスクでは、Windowsサービスの作成方法を学ぶ必要はありません。


9
スケジュールされたタスクは、ユーザーがログインしていなくても実行できますが、ユーザーのパスワードをスケジュールエージェントに提供する必要があります。
MarekJedliński、2008

1
@moodforadayアカウントにパスが設定されていないNT AUTHORITY\LocalService場合(例:、またはNT AUTHORITY\NetworkService)。アカウントにパスワードがないため、指定されたパスワードは無視されます。
Ian Boyd 2013年

4
  1. 適切な権限でWindowsサービスを設定およびロックダウンする方が簡単です。
  2. サービスはより「見える」ことを意味し、誰もが(つまり:技術者が)どこを見ればよいかを知っています。

5
最初のポイントは、スケジュールされたタスクにも適用されます。「もっと見える」の意味がわかりません。スケジュールされたタスクは、サービスと同じくらい簡単に表示できます。
w4g3n3r 2008

@ w4g3n3r:ほとんどの技術者は、何が実行されているかを確認するためにWindowsサービスを確認する方法を知っています。さらに、それがサービス(および実行中)の場合、通常のタスクマネージャーリストに表示されます。スケジュールされたタスクを使用する人はほとんどいません。
NotMe 2008

さらに、技術者は問題が発生したときにイベントビューアを確認することを知っています。スケジュールされたタスクは、その情報をファイルシステムのログファイルに保存します。私は、ほとんどの人がそれをどこで探すべきかさえわからないことに賭けても構わないと思っています。
NotMe 2008

1
統計がない限り、「スケジュールされたタスクを使用する人は非常に少ない」とは思いません。私はいつも彼らに会います。2分ごとに何かを実行する必要がある非コーダーの場合、スケジュールされたタスクに移動するだけですが(サービスにアクセスするのと同じ難しさ)、新しいタスクを作成するにはウィザードがあります。したがって、ユーザーが知っておく必要があるのは、プログラムまたはスクリプトの場所と、実行する頻度だけです。今、あなたがコーディング方法を知っていて、マシンがネットワーク上にあり、ログインを保護する必要があり、複数のインスタンス(1つが2分を超える場合)を防ぐための組み込みの処理が必要な場合は、サービスを利用します。
ゲイリー

4
「ほとんどの技術者はWindowsサービスを見て、何が実行されているかを確認する方法を知っていますこれはサービスの問題の1つです。それらは常に実行されます-実行中のプロセスの記録のためにユーザーとカーネルのリソースを消費します。そのため、Microsoftはできるだけ多くのサービスを単一のプロセス(svchost.exe)にマージしました。プロセスを用意するだけで、不必要なリソースの消費を排除できます。
Ian Boyd

2

両方を提供しないのはなぜですか?

過去に私は「コア」ビットをライブラリに入れ、Whatever.GoGoGo()への呼び出しをサービスとコンソールアプリの両方でラップしました。

あなたが2分ごとに発砲しているものでは、オッズはまともではありません(たとえば、単に「ping」タイプの関数)。ラッパーは、単一のメソッド呼び出しといくつかのロギングよりもはるかに多くを含む必要はありません。


2

これは古い質問ですが、私が直面したことを共有したいと思います。

最近、レーダーのスクリーンショット(気象Webサイトから)をキャプチャし、10分ごとにサーバーに保存するように要求されました。

このため、WebBrowserを使用する必要がありました。私は通常Windowsサービスを作成するので、これも1つのサービスにすることにしましたが、クラッシュし続けます。これは、イベントビューアの障害のあるモジュールパスで見たものです :C:\ Windows \ system32 \ MSHTML.dll

タスクが緊急で、研究と実験の時間が非常に少なかったので、シンプルなコンソールアプリケーションを使用することを決め、それをタスクとしてトリガーし、スムーズに実行しました。

Mark Ransomの承認済み回答で推奨されているJon Galloway記事が本当に気に入りました。

最近、サーバーのパスワードが私に通知されずに変更され、すべてのサービスがログオンできなかったため、実行に失敗しました。したがって、記事で主張しているpplは、これが問題であるとコメントしています。私はWindowsサービスが同じ問題に直面する可能性があると思います(間違っている場合は修正してください。私は初心者です)

また、タスクスケジューラのウィンドウがポップアップしたり、コンソールウィンドウがポップアップしたりする場合にも言及しました。私はそれに直面したことがありません。ポップアップする可能性がありますが、少なくとも非常に瞬間的です。


Jon Gallowayの記事にはいくつかの良い点があると思いました。また、パスワードの変更などが原因でスケジュールされたタスクの実行が失敗したという苦情に対しては、スケジュールされたタスクの実行が失敗した場合に対応できるため、ユーザーまたは必要なことを通知できます。ここに解決策を参照してください。superuser.com/questions/249103/...
ダンCsharpster

1

一般に、コアメッセージは、コード自体がすべての「トリガー/クライアント」から実行可能でなければならないということであり、そうでなければなりません。したがって、1つのアプローチから別のアプローチに切り替えるのは、ロケットサイエンスではありません。

以前は多かれ少なかれ常にWindowsサービスを使用していましたが、ますます多くのお客様が段階的にAzureに切り替えており、コンソールアプリ(スケジュールされたタスクとしてデプロイされたもの)からAzureのWebJobへの交換がはるかに簡単ですWindowsサービスでは、今のところスケジュールされたタスクに焦点を当てています。制限に達した場合は、Windowsサービスプロジェクトを立ち上げて、そこから同じロジックを呼び出します(顧客がOnPremで作業している限り)。

BR、y


0

Windowsサービスは、完了するまでより多くの忍耐力を求めています。少しハードなデバッグとインストールがあります。顔のないです。秒、分、または時間ごとに実行する必要があるタスクが必要な場合は、Windowsサービスを選択する必要があります。

スケジュールされたタスクはすぐに開発され、顔があります。毎日または毎週のタスクが必要な場合は、スケジュールされたタスクを使用できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.