web-dev-qa-db-ja.com

スケジュールされたタスクを実行する最良の方法

今日、ASP.NET Webサイトのスケジュールされたタスクを実行するためのコンソールアプリケーションを構築しました。しかし、このアプローチは少しエラーが発生しやすく、保守が難しいと思います。スケジュールされたタスクを実行する方法(windows/IIS/ASP.NET環境)

更新:

タスクの例:

  • データベース内のメールキューからメールを送信する
  • データベースから古いオブジェクトを削除する
  • Google AdWordsから統計情報を取得し、データベースにテーブルを記入します。
222
Niels Bosma

Webサイトのすべてのタスク(スケジュールする必要があります)はWebサイト内に保持され、特別なページから呼び出されます。次に、このページを頻繁に呼び出す単純なWindowsサービスを作成しました。ページが実行されると、値が返されます。さらに作業が必要なことがわかっている場合は、すぐにページを再度実行します。それ以外の場合は、しばらくしてから実行します。これは私にとって非常にうまく機能し、すべてのタスクロジックをWebコードで保持しています。単純なWindowsサービスを作成する前に、Windowsスケジューラを使用してx分ごとにページを呼び出しました。

これを実行する別の便利な方法は、 Pingdom のような監視サービスを使用することです。サービスコードを実行するページにHTTPチェックを向けます。ページに結果を返すようにします。この結果を使用して、Pingdomをトリガーして、何か問題がある場合にアラートメッセージを送信します。

70
Brettski

Stackoverflow用のJeff Atwoodによるこの手法 は、私が遭遇した最も簡単な方法です。 ASP.NETのキャッシュシステムに組み込まれた「キャッシュアイテムが削除された」コールバックメカニズムに依存しています。

更新:Stackoverflowはこのメソッドを超えています。これはWebサイトの実行中にのみ機能しますが、非常に単純な手法であり、多くの人々に役立ちます。

また、チェックアウト Quartz.NET

126
BC.

カスタムWindowsサービス を作成します。

スケジュールされたコンソールアプリとして設定されたミッションクリティカルなタスクがいくつかあり、それらを保守するのが難しいことがわかりました。 DBのスケジュールを数分ごとにチェックする「ハートビート」を使用してWindowsサービスを作成しました。本当にうまくいきました。

そうは言っても、重要でないメンテナンスタスクのほとんどには、スケジュールされたコンソールアプリを使用します。壊れていない場合は、修正しないでください。

30

これはすべての関係者にとって簡単であることがわかりました。

  • DoSuchAndSuchProcessなどのWebサービスメソッドを作成します。
  • このwebmethodを呼び出すコンソールアプリを作成します。
  • タスクスケジューラでコンソールアプリをスケジュールします。

この方法を使用すると、すべてのビジネスロジックがWebアプリに含まれますが、Windowsタスクマネージャーまたは他の商用タスクマネージャーの信頼性があり、キックオフして実行レポートなどのリターン情報を記録できます。ページに投稿する代わりにWebサービスを使用すると、Webサービスから返されるデータを取得するのが簡単になるため、少し利点があります。

17
Daniel Auger

車輪を再発明する理由は、ThreadingクラスとTimerクラスを使用してください。

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }
10

Windowsスケジューラを使用してWebページを実行します。

悪意のあるユーザーまたは検索エンジンのスパイダーが実行するのを防ぐには、スケジュールされたタスクを設定するときに、クエリ文字列を使用してWebページを呼び出します。つまり、mypage.aspx?from = scheduledtask

次に、ページの読み込みで条件を使用します。if(Request.Querystring ["from"] == "scheduledtask"){// executetask}

これにより、検索エンジンのスパイダーや悪意のあるユーザーがスケジュールされたタスクを実行できなくなります。

8
philberg

このライブラリはチャームのように機能します http://www.codeproject.com/KB/cs/tsnewlib.aspx

.NETコードを使用して、Windowsのスケジュールされたタスクを直接管理できます。

4
labilbe

さらに、アプリケーションがSQL SERVERを使用している場合は、SQLエージェントを使用してタスクをスケジュールできます。これは、データ駆動型の繰り返し発生するコード(電子メールアラーム、定期メンテナンス、パージなど)を配置する場所です。 SQL Agentに組み込まれている優れた機能は、重要なタスクが失敗した場合に警告できる失敗通知オプションです。

3
Zachary

スケジュールされたタスクの種類がどういう意味かわかりません。 「毎時間、foo.xmlを更新する」タイプのタスクのようなものを意味する場合は、Windowsスケジュールタスクシステムを使用します。 (「at」コマンド、またはコントローラー経由)。コンソールアプリを実行するか、プロセスを開始する特別なページを要求します。

編集:追加する必要があります。これは、スケジュールされたポイントでIISアプリを実行するのに適した方法です。したがって、30分ごとにDBをチェックし、一部のデータについてリマインダーをユーザーにメールで送信するとします。スケジュールされたタスクを使用してこのページを要求し、IIS処理を取得できます。

ニーズがより複雑な場合は、Windowsサービスを作成し、ループを実行して必要な処理を実行することを検討できます。これには、スケーリングまたは管理のためにコードを分離するという利点もあります。欠点として、Windowsサービスに対処する必要があります。

2
MichaelGG

サーバーを所有している場合は、Windowsタスクスケジューラを使用する必要があります。 AT /?を使用しますコマンドラインからオプションを表示します。

そうしないと、Webベースの環境から、一定の間隔で特定のページにリクエストを送信するために別のマシンをセットアップするような厄介なことをしなければならない場合があります。

2
t3rse

ASP.NETプロジェクトで Abidar を使用しました(ここに 背景情報 があります)。

この方法の唯一の問題は、ASP.NET Webアプリケーションがメモリからアンロードされた場合(つまり、使用率が低いため)、タスクが実行されないことです。私が試したことの1つは、5分ごとにWebアプリケーションをヒットするタスクを作成し、それを生きたままにしますが、これは確実に動作するようには見えなかったので、代わりにこれを行うためにWindowsスケジューラと基本的なコンソールアプリケーションを使用しています。

理想的なソリューションはWindowsサービスを作成することですが、これは不可能かもしれません(つまり、共有ホスティング環境を使用している場合)。また、Webアプリケーション内で物事を維持するために、メンテナンスの観点から物事を少し簡単にします。

2
Mun

別の方法を次に示します。

1)タスクがDUEであるか、起動が遅れている場合にタスクを起動する「ハートビート」Webスクリプトを作成します。

2)webscriptにヒットし、定期的に実行するようにスケジュールされたプロセスを(同じWebサーバー上に)どこかに作成します。 (例:IEまたはwhathaveyouを使用してheatbeatスクリプトを静かに起動するWindowsスケジュールタスク)

タスクコードがWebスクリプトに含まれているという事実は、純粋にコードを維持するためですwithin Webアプリケーションのコードベース(前提は両方が互いに依存しているということです)、 Web開発者が管理しやすくなります。

別のアプローチは、すべてのスケジュール作業自体を実行する実行可能サーバースクリプト/プログラムを作成し、実行可能ファイル自体をスケジュールされたタスクとして実行することです。これにより、Webアプリケーションとスケジュールされたタスクの間の基本的な分離が可能になります。したがって、Webアプリ/データベースがダウンしたりアクセスできない場合でも、スケジュールされたタスクを実行する必要がある場合は、このアプローチを使用する必要があります。

1
Matias Nino

'ThreadPool.RegisterWaitForSingleObject'メソッドを使用して、間隔を置いてコードを実行するWindowsサービスを簡単に作成できます。それは本当になめらかで、セットアップが非常に簡単です。このメソッドは、フレームワークのタイマーを使用するよりも合理化されたアプローチです。

詳細については、以下のリンクをご覧ください。

Windowsサービスを使用した.NETでの定期プロセスの実行:
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html

1
atconway

コンソールアプリケーションも使用します。 Log4netなどのログツールを使用すると、その実行を適切に監視できます。また、適切に設計されていれば、2つの間で同じコードライブラリの一部を共有している可能性があるため、Webページよりもメンテナンスが難しいのかわかりません。

これらのタスクを定期的に実行することに反対する場合は、Webサイトの管理セクションにキューとして機能するWebページを作成できます。ユーザーがタスクを実行するリクエストを入力すると、MyProcessQueueテーブルに空の日付スタンプレコードが挿入され、スケジュールされたタスクはX分ごとにMyProcessQueueの新しいレコードをチェックします。そのようにして、顧客が実行したい場合にのみ実行されます。

これらの提案がお役に立てば幸いです。

0
Kyle Ballard

1つのオプションは、Windowsサービスを設定し、それを取得してスケジュールされたタスクを呼び出すことです。

私がタイマーを使用したwinformsでは、これがASP.NETでうまく機能するとは思わない

0
AJM