回答:
更新:
私の元の回答からほぼ4年後、この回答は非常に古くなっています。TopShelfが登場して以来、Windowsサービスの開発は簡単になりました。次に、フェイルオーバーをサポートする方法を理解する必要があります...
元の回答:
私は本当にWindowsスケジューラのファンではありません。@moodforallが上で指摘したように、ユーザーのパスワードを提供する必要があります。これは、誰かがそのユーザーのパスワードを変更したときに楽しいことです。
Windowsスケジューラのもう1つの大きな問題は、バックグラウンドプロセスとしてではなく、対話的に実行されることです。RDPセッション中に20分ごとに15個のMS-DOSウィンドウがポップアップ表示されると、代わりに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 (Dead Link)
私はこのようなWindowsサービスを何年も実行してきましたが、私にとってはうまくいきました。私はまだ人々が同意する推奨パターンを見ていません。ちょうどあなたのために働くことをしてください。
NT AUTHORITY\NetworkService
は、権限が制限されたアカウントです。
ここにいくつかの誤報があります。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
が唯一のオプションです。
Local Service
(別名NT AUTHORITY\LocalService
ではなく)LocalSystem
(別名.\LocalSystem
)。前者には制限付きの権限がありますが、後者は管理者です
LocalService
とNetworkService
で利用できるschtasks
以降V2 Vistaおよび可能であれば優先されなければなりません。当時、これschtasks
はXPとServer 2003 System
の古いバージョンのマニュアルtechnet.microsoft.com/en-us/library/bb490996.aspxの
アプリの起動と終了のオーバーヘッドは何ですか?2分ごとがかなり頻繁です。サービスを使用すると、アプリケーションをそれほど頻繁に実行するよりもシステムをスムーズに実行できます。
どちらのソリューションでも、ユーザーがログインしていないときにプログラムを実行できるため、違いはありません。ただし、サービスの記述は通常のデスクトップアプリよりもやや複雑です。TCP/ IP、名前付きパイプなどを介してサービスアプリと通信する別のGUIクライアントが必要になる場合があります。
ユーザーの視点から、どちらが制御しやすいのかと思います。ほとんどの非技術ユーザーにとって、サービスとスケジュールされたタスクの両方はほとんど手の届かないところにあります。つまり、サービスが存在していることに気づかず、構成/停止/再スケジュールなどが可能です。
.NET開発では、通常、すべてのログ出力をコンソールウィンドウに実行するコンソールアプリケーションを開発することから始めます。ただし、コマンド引数を指定して実行した場合、これはコンソールアプリケーションにすぎません/console
。このパラメーターなしで実行すると、Windowsサービスとして機能します。これは、独自にコード化した独自のスケジュールされたタイマーで実行を継続します。
私の考えでは、Windowsサービスは通常、長時間実行されるアプリケーションではなく、他のアプリケーションを管理するために使用されます。または..それらは、SQL Server、BizTalk、RPC接続、IIS(IISは技術的に他のプロセスへの負荷を軽減しますが)などの継続的に実行されるヘビー級アプリケーションです。
個人的には、ファイルサービスのコピー/同期、メールの一括送信、ファイルの削除またはアーカイブ、データの修正(他の回避策が利用できない場合)などの定期的なメンテナンスタスクやアプリケーションでは、ウィンドウサービスよりもスケジュールされたタスクを優先します。
1つのプロジェクトでは、8または9のWindowsサービスの開発に携わっていましたが、これらはメモリ内で待機し、インスタンスごとに20MB以上のメモリを消費しています。スケジュールされたタスクはビジネスを行い、メモリをすぐに解放します。
「サーブ」という言葉は「サーブ」と共通の何かを共有しています。それは常に実行されていると予想され、「サーブ」します。タスクはタスクです。
ロールプレイ。私が別のオペレーティングシステム、アプリケーション、またはデバイスであり、サービスを呼び出した場合、サービスが実行中であることを期待し、応答を期待します。私(os、app、dev)が分離されたタスクを実行するだけでよい場合は、タスクを実行しますが、通信(おそらく双方向通信)が必要な場合は、サービスが必要です。これは、2つの情報をやり取りする最も効果的な方法、または1つのタスクを実行したい1つの方法に関係しています。
次に、スケジューリングの側面があります。特定の時間に何かを実行したい場合は、スケジュールします。いつ必要になるかわからない場合、または「オンザフライ」で必要な場合は、サービスをご利用ください。
これは人間の相互作用や他の人との働き方と非常によく似ているため、私の応答は本質的に哲学的です。コミュニケーションの技術を理解し、エンティティがその役割を理解するほど、この決定は容易になります。
すべての哲学は別として、あなたが「迅速にプロトタイピング」しているときは、私のIT部門がよく行うように、やりがいを持たせるために必要なことは何でもします。プロトタイピングと概念実証のものが途絶えたら、通常は初期の計画と発見において、長期的な持続可能性にとってより信頼できるものを決定する必要があります。
結局のところ、結論は多くの要因に大きく依存していますが、うまくいけば、混乱の代わりに洞察が得られたと思います。
Windowsサービスには誰もログインする必要はありません。Windowsには、サービスの結果を停止、開始、および記録する機能があります。
スケジュールされたタスクでは、Windowsサービスの作成方法を学ぶ必要はありません。
NT AUTHORITY\LocalService
場合(例:、またはNT AUTHORITY\NetworkService
)。アカウントにパスワードがないため、指定されたパスワードは無視されます。
両方を提供しないのはなぜですか?
過去に私は「コア」ビットをライブラリに入れ、Whatever.GoGoGo()への呼び出しをサービスとコンソールアプリの両方でラップしました。
あなたが2分ごとに発砲しているものでは、オッズはまともではありません(たとえば、単に「ping」タイプの関数)。ラッパーは、単一のメソッド呼び出しといくつかのロギングよりもはるかに多くを含む必要はありません。
これは古い質問ですが、私が直面したことを共有したいと思います。
最近、レーダーのスクリーンショット(気象Webサイトから)をキャプチャし、10分ごとにサーバーに保存するように要求されました。
このため、WebBrowserを使用する必要がありました。私は通常Windowsサービスを作成するので、これも1つのサービスにすることにしましたが、クラッシュし続けます。これは、イベントビューアの障害のあるモジュールパスで見たものです :C:\ Windows \ system32 \ MSHTML.dll
タスクが緊急で、研究と実験の時間が非常に少なかったので、シンプルなコンソールアプリケーションを使用することを決め、それをタスクとしてトリガーし、スムーズに実行しました。
Mark Ransomの承認済み回答で推奨されているJon Gallowayの記事が本当に気に入りました。
最近、サーバーのパスワードが私に通知されずに変更され、すべてのサービスがログオンできなかったため、実行に失敗しました。したがって、記事で主張しているpplは、これが問題であるとコメントしています。私はWindowsサービスが同じ問題に直面する可能性があると思います(間違っている場合は修正してください。私は初心者です)
また、タスクスケジューラのウィンドウがポップアップしたり、コンソールウィンドウがポップアップしたりする場合にも言及しました。私はそれに直面したことがありません。ポップアップする可能性がありますが、少なくとも非常に瞬間的です。
一般に、コアメッセージは、コード自体がすべての「トリガー/クライアント」から実行可能でなければならないということであり、そうでなければなりません。したがって、1つのアプローチから別のアプローチに切り替えるのは、ロケットサイエンスではありません。
以前は多かれ少なかれ常にWindowsサービスを使用していましたが、ますます多くのお客様が段階的にAzureに切り替えており、コンソールアプリ(スケジュールされたタスクとしてデプロイされたもの)からAzureのWebJobへの交換がはるかに簡単ですWindowsサービスでは、今のところスケジュールされたタスクに焦点を当てています。制限に達した場合は、Windowsサービスプロジェクトを立ち上げて、そこから同じロジックを呼び出します(顧客がOnPremで作業している限り)。
BR、y