SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

ASP.NETでWindowsサービスのような機能を実装する方法

ASP.NETで定期的なJobを実行する

  • X ポスト
  • このエントリーをはてなブックマークに追加

ScheduleServiceクラスの実装

System.Web.Caching.Cacheクラスとコールバック関数

 ASP.NETのCacheオブジェクトにはデータをキャッシュすることが可能ですが、キャッシュを更新する際に有効期限を指定してデータをキャッシュさせることが可能です。また有効期限が切れたときにある関数を実行させることができます。このコールバックメソッド内で、再度有効期限付き&コールバックメソッドの登録を行うことで、定期的に関数を実行するということが可能になります。

 添付したサンプルコードはジョブの実行の部分も混在しているので、分かりやすいようにコールバックメソッドの再登録の部分だけを以下に示します。

public static void Start()
{
     ScheduleService.RegisterTickFunction();
}
private static void RegisterTickFunction()
{
    ScheduleService.zCache.Insert(
        ScheduleService.zSingleton.CacheKey,
        "ScheduleService",
        null,
        DateTime.MaxValue,
        TimeSpan.FromMinutes(1),
        CacheItemPriority.Normal,
        new CacheItemRemovedCallback(ScheduleService.Tick));
}
private static void Tick(String inKey,
                         Object inValue,
                         CacheItemRemovedReason inReason)
{
     ScheduleService.RegisterTickFunction();
}

 サービスを開始するには以下のように記述します。サンプルソースでは「Global.cs」に記述してあります。

void Main()
{
     ScheduleService.Start();
}

 これにより関数がキャッシュオブジェクトに登録されます。

 1分後に有効期限が切れると、コールバックメソッドTickが実行され、Tickメソッド内でキャッシュオブジェクトの登録が行われます。結果、1分ごとに定期的に処理が実行されるようになります。

HttpApplicationクラス

 「Global.asax」ファイルの実態はHttpApplicationクラスの継承したクラスです。

 「Global.asax」中にインラインで記述しても良いのですが、そうすると開発環境での動作がちょっと遅いので私は別ファイルに記述するようにしています。「Global.asax」で

<%@ Application Language="C#"
    CodeBehind="~/App_Code/Global.cs"
    Inherits="Higuchi.WindowsServiceSample.Biz.Global" %>

 と記述することにより、任意のクラスを指定できます。CodeBehindは物理ファイルの位置、Inheritsは名前空間を含むクラスの名前を指定します。このようにすることで、アプリケーション全体でのログの取得やセキュリティの認証などの処理を実装しやすくなります。

シングルトンパターンの実装

 ScheduleServiceクラスは複数のインスタンスである必要はないので、シングルトンパターンで実装します。シングルトンパターンとはアプリケーション全体で、インスタンスが1つしか生成しないようににするためのデザインパターンです。ポイントは、

  • 自分自身への参照を保持するstaticな変数
  • コンストラクタをprivateにする
  • 唯一のインスタンスへのアクセスを提供するstaticなプロパティの実装

 となります。

マルチスレッドの考慮

 Webアプリケーションは複数のリクエストがマルチスレッドで実行されます。static変数へのアクセスは適切にlockをかけないと再現性の低い不具合が埋め込まれ、原因の特定が困難になります。

 lockをかけるべき部分は、Startメソッドで最初にコールバック関数を登録する部分と、登録されたジョブを実行する部分にかけるとなります。lockステートメントにより、複数のスレッドが同時にアクセスしたとしても、1つのスレッドのみが該当部分を実行することを保証できます。

複数サイトでの利用

 この機能を利用する際、複数のWebサイトをたててスケールアウトするような場合では、少し工夫が必要です。

 例えば定期的にDBサーバの不要なデータを削除する処理を実行しているとします。それぞれのWebサイトでDBに対して削除処理をするのは無駄なので、どれか1つのサイトのみ実行するようにコードを書き換えたりする必要が出てくるでしょう。

 解決策として、「Web.Config」ファイルなどにサービスを有効にするかどうかを設定できるように機能拡張します。そして複数あるサイトのうち1つのサイトのみサービスが実行されるように設定ファイルを構成します。詳細はサンプルには入っていませんが、ヒントとして参考にしてみてください。

まとめ

 ASP.NETにWindowsServiceのような機能を実装することで、設定の手間などを低減できます。

 このクラスを利用すれば、指定した時刻にメールを送ったり、毎日1回古いデータを削除したり、1時間ごとに新しい情報がないかチェックしたりなどの機能を簡単に作成できるでしょう。

 参考になれば幸いです。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

Higty(Higty)

C#マスターになるべく勉強中の身分です。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1148 2007/09/30 09:38

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング