web-dev-qa-db-ja.com

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

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

109
Manu

更新:

最初の回答から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サービスを何年も実行していますが、私にとってはうまくいきます。人々が同意する推奨パターンはまだ見ていません。ちょうどあなたのために働くものをしてください。

47
Rebecca

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

/ ru SYSTEM

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

[〜#〜] edit [〜#〜]

OSとタスク自体の要件に応じて、/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. は、VistaおよびServer 2008から利用可能です。

XP and Server 2003では、systemが唯一のオプションです。

16
Amit Naidu

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

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

ユーザーのPOVから、どちらを制御する方が簡単かと思います。サービスとスケジュールされたタスクの両方は、ほとんどの技術者でないユーザーにとってはほとんど手の届かないところにあります。

11

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

私の考えでは、Windowsサービスは通常、長時間実行されるアプリケーションではなく、他のアプリケーションの管理に使用されます。 OR ..これらは、SQL Server、BizTalk、RPC Connections、IISなどの継続的に実行されるヘビーウェイトアプリケーションです(たとえIISが他のプロセスに技術的にオフロードしても)。

個人的には、ファイルのコピー/同期、電子メールの一括送信、ファイルの削除またはアーカイブ、データ修正(他の回避策が利用できない場合)などの反復的なメンテナンスタスクおよびアプリケーションのために、Windowsサービスよりもスケジュールされたタスクを好みます。

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

10

「serv'ice」という言葉は、「serv'er」と共通点を共有しています。常に実行されていること、および「サービス」が期待されます。タスクはタスクです。

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

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

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

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

結論として、多くの要因に大きく依存していますが、これが混乱の代わりに洞察を提供することを願っています。

8
Dan Cortese

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

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

4
Mark Ransom
  1. 適切なアクセス許可を使用してWindowsサービスをセットアップおよびロックダウンする方が簡単です。
  2. サービスはより「目に見える」ものであり、誰もが(つまり技術者が)どこを見ればよいかを知っていることを意味します。
4
NotMe

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

最近、レーダーのスクリーンショットを(気象ウェブサイトから)キャプチャし、10分ごとにサーバーに保存する必要がありました。

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

タスクは緊急であり、調査と実験の時間が非常に短いため、単純なコンソールアプリケーションを使用してタスクとしてトリガーし、スムーズに実行することにしました。

Jon Gallowayの記事 Mark Ransomの受け入れられた回答で推奨されているのが本当に好きだった.

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

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

2
Silver

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

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

あなたが2分ごとに発射するものでは、オッズはまともです(たとえば、「ping」タイプの機能)。ラッパーには、1回のメソッド呼び出しといくつかのロギング以上のものを含める必要はありません。

2
aspdotnoob

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

以前は、ほぼ常にWindowsサービスを使用していましたが、徐々に多くのお客様が段階的にAzureに切り替えており、コンソールアプリ(スケジュールされたタスクとしてデプロイ)からAzureのWebJobへのスワップは、 Windowsサービスであるため、現時点ではスケジュールされたタスクに焦点を当てています。制限に直面した場合は、Windowsサービスプロジェクトを立ち上げ、そこから同じロジックを呼び出します(顧客がOnPremを使用している限り)。

BR、y

0
ynnok

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

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

0
Oguzhan KIRCALI