質問
このコードを考えてみましょう...
using System.Threading;
//...
Timer someWork = new Timer(
delegate(object state) {
//Do some work here...
},
null, 0, 60000);
HttpContext.Current.Application["SomeWorkItem"] = someWork;
これは危険なことなのでしょうか?サイトの実行中にバックグラウンドで何らかの作業を実行するためにアプリケーションにタイマーをキャッシュするのは安全なように思えますが、これについて何らかの経験がある人はいるだろうかと思いました。
バックグラウンドで実行するサービスを作成したほうが確実に優れていると確信していますが、それが常に選択肢であるとは限りません。これは代替手段ですか?
解決
System.Threading.Timer は ASP.Net と同じように ThreadPool のスレッドを使用するため、これは一般的に悪い考えです。
何らかの理由でタイマー デリゲートがブロックまたは停止した場合、タイマーはタイムアウト期間後に新しいスレッドを開始するだけで、ASP.net で使用できるスレッドが消費されます。
それらがすべてブロックされ始めると、事実上、それ以上 Web リクエストを処理できなくなります (おそらく悪いことです)。
他のヒント
これの問題は、プロセスがまだ生きていることが保証されていないことです。IIS は基本的に必要に応じてプロセスを再利用するため、プロセスが実行されなくなるリスクがあります。
この作業を実行する必要がある場合は、それを Web 呼び出しにコーディングするか、サーバーのバックグラウンドでサービスを実行する必要があります。
これは危険です。ワーカー プロセスがリサイクルされたり、AppDomain がクラッシュして作業項目が強制終了されたりする場合があり、実行中の内容を復元したい場合がありますが、それが不可能な場合もあります。
作業項目をサービスに取り出すことができれば、Windows サービスでも問題ないかもしれません。ただし、作業に HttpContext が必要な場合は、Windows サービスに Web サービスを呼び出して定期的に呼び出しを実行することもできますが、これはおそらく理想的ではありませんが、機能する可能性があります。
それは当然ですが、冗談として、サイトが閉鎖された場合に作業を実行する必要がなくなったらどうなるでしょうか?Application_Start イベントに関連付けられており、ユーザーがサイトを閲覧している間のみ実行する必要がある場合、その時点でのリスクは何でしょうか?
良い答えですね。内部でどのように機能するかもう少し知りたいです。
サイト上のページを実行するようにスケジュールされたタスクを設定することをお勧めします。私は通常、次のようにスケジュールされたタスクを .vbs ファイルに指定します。
On Error Resume Next Dim objRequest Dim URL Set objRequest = CreateObject("Microsoft.XMLHTTP") URL = "http://www.mywebsite.com/cron/pagetorun.ashx" objRequest.open "POST", URL , false objRequest.Send Set objRequest = Nothing
Omar Al Zabir は、この目的でのキャッシュ項目コールバックの使用に関する優れた投稿を行っています。