- PR -

System.Threading.Timerの動作について(C#)

投稿者投稿内容
mifu
会議室デビュー日: 2005/05/09
投稿数: 4
投稿日時: 2005-05-09 15:54
お世話になっております。
.NET C# 初心者です。
どなたかお分かりの方がいらっしゃいましたら、ご教授ください。

1回/日のタイミングで動作させたい処理があります。
そのためThreading.Timerを利用していますが
ログで確認したところ、30日の内、8日は動作していないという状況です。
(それ以外は、指定時刻に正確に動作しています。)
比較的、アクセス数が少ない日の動作が不安定のように感じています。
毎日正確に処理を動作させるには、どうような対応を取るべきなのでしょうか?

[環境]
 Windows2003Server
 .NET C#
[コード]
 ・
 ・
 if(DateTime.Compare(DateTime.Now, objTime) > 0) {
  tsSpan = objTime.AddDays(1).Subtract(DateTime.Now);
 } else {
  tsSpan = objTime.Subtract(DateTime.Now);
 }

 System.Threading.Timer ThreadTimer =
   new System.Threading.Timer(
   new TimerCallback(this.Order), null, tsSpan, TimeSpan.FromDays(1));
 ・
 ・
 ・


初投稿になりますので、情報など不足分がありましたらご指摘ください。
よろしくお願いします。

甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2005-05-09 16:28
このアプリケーションはどのような形態のアプリケーションなのでしょうか?ASP.NET?Windows Forms?サービス?
このThreading.Timerのインスタンスを初期化するコードは、いつどの様なタイミングで実行されるのでしょうか?
ThreadTimer変数の寿命はこの関数内ですよね?ガベージコレクタに回収されてしまったりしないのでしょうか?

負荷がどうの言っていることから察してASP.NETかWEBサービスなのですかね?
Threadint.Timeはインスタンスを構築してから、アプリケーションが終了する事無く1日以上経過した時点でイベントが発生するわけですが、それで本当に仕様上問題ないんでしょうか?途中でリブートした場合は実行されなくてもOKなの?
mifu
会議室デビュー日: 2005/05/09
投稿数: 4
投稿日時: 2005-05-09 16:47
>このアプリケーションはどのような形態のアプリケーションなのでしょうか?
ASP.NETです。
商品検索用ページとして24時間稼動しており、1日に1度のタイミングである処理を行っています。

>このThreading.Timerのインスタンスを初期化するコードは、いつどの様なタイミングで実行されるのでしょうか?
Application_Start時に呼び出され
Application動作中は、スレッドが動きつづけているイメージです。

>ガベージコレクタに回収されてしまったりしないのでしょうか?
実行されていない日が継続するのではなく何日かに一度実行されない日があるという
状況なので、ガベージに回収されていないのでは?と考えています。。。
知識不足で申し訳ありません。。
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2005-05-09 17:00
引用:

mifuさんの書き込み (2005-05-09 16:47) より:
Application_Start時に呼び出され
Application動作中は、スレッドが動きつづけているイメージです。


スレッドが動き続けるっていうのはどういうことでしょうか??
Timerのインスタンスは、HttpApplicationインスタンスのメンバに持っているということでしょうか?

引用:

>ガベージコレクタに回収されてしまったりしないのでしょうか?
実行されていない日が継続するのではなく何日かに一度実行されない日があるという
状況なので、ガベージに回収されていないのでは?と考えています。。。
知識不足で申し訳ありません。。


ASP.NETでは、ワーカープロセスは何らかの原因で再起動される場合があります。
アプリケーションドメインも再起動される場合があります。
※例えばデフォルトでは、確か要求が20分こないとアプリケーションは終了します。

このため、ガーベージコレクションだけではなく、アプリケーションが終了してしまっている可能性があります。
たまたま要求がくれば、アプリケーションが再度起動され、次の終了までに指定の時刻が来れば正常に処理されるわけです。

--追記
>比較的、アクセス数が少ない日の動作が不安定のように感じています。

とのことですので、この可能性が高いと思います。
アクセス数が少ないということは、間隔が空いてアプリケーションが終了してしまう可能性が高いということです。


[ メッセージ編集済み 編集者: なちゃ 編集日時 2005-05-09 17:09 ]
kanai
ベテラン
会議室デビュー日: 2004/09/13
投稿数: 98
投稿日時: 2005-05-09 17:14
引用:

毎日正確に処理を動作させるには、どうような対応を取るべきなのでしょうか?



コンソールアプリケーションにしてタスクスケジューラに登録して起動する、
というのはいかがでしょうか。
mifu
会議室デビュー日: 2005/05/09
投稿数: 4
投稿日時: 2005-05-09 18:06
引用:

なちゃさんの書き込み (2005-05-09 17:00) より:
スレッドが動き続けるっていうのはどういうことでしょうか??
Timerのインスタンスは、HttpApplicationインスタンスのメンバに持っているということでしょうか?


ご指摘の通りです。
サンプルコードを記述する際に、メンバの宣言位置を変更してしまっていました。

引用:

ASP.NETでは、ワーカープロセスは何らかの原因で再起動される場合があります。
アプリケーションドメインも再起動される場合があります。
※例えばデフォルトでは、確か要求が20分こないとアプリケーションは終了します。

このため、ガーベージコレクションだけではなく、アプリケーションが終了してしまっている可能性があります。
たまたま要求がくれば、アプリケーションが再度起動され、次の終了までに指定の時刻が来れば正常に処理されるわけです。


理解しやすい説明をありがとうございました。

そこで、web.configを確認するとtimeout="360"(sessionState)となっていました・・・。
設定値の根拠は分かりませんが、この値が効いていないかと思い
MAX値を調べましたが見つけることができませんでした。
ワーカープロセスの再起動時刻は設定しており、スレッド動作時刻とは重ならないように設定しています。
説明頂き、まさに指摘のとおりだと納得したのですが、新たな疑問が出てしまいました。
他にアプリケーションが終了してしまうタイミングあるのでしょうか?
Jitta
ぬし
会議室デビュー日: 2002/07/05
投稿数: 6267
お住まい・勤務地: 兵庫県・海手
投稿日時: 2005-05-09 22:36
> ワーカープロセスの再起動時刻は設定しており
 デフォルトはInfinite、つまり再起動しないのですが、それを設定している?
 時間間隔で指定するはずですが、時刻指定?
 [<processModel> 要素]じゃないのかな?


 通常、この手のものはkanaiさんのおっしゃるようにタスクスケジューラに登録するか、Windowsサービスアプリケーションとして構築します。
 Webアプリケーションは、いつ再起動するかわかりません。再起動するタイミングは、MSDNの[セッション状態]に列挙されています。
 セッションの保持時間とアプリケーションが再起動するタイミングは関係ないですよ。セッションの保持時間内であっても、アプリケーションは再起動します。

_________________
なちゃ
ぬし
会議室デビュー日: 2003/06/11
投稿数: 872
投稿日時: 2005-05-09 23:50
引用:

Jittaさんの書き込み (2005-05-09 22:36) より:
> ワーカープロセスの再起動時刻は設定しており
 デフォルトはInfinite、つまり再起動しないのですが、それを設定している?


ありゃ、ちょっと勘違いしてたみたいです>デフォルトInfinite
ま、いずれにしても、
引用:

 通常、この手のものはkanaiさんのおっしゃるようにタスクスケジューラに登録するか、Windowsサービスアプリケーションとして構築します。


の方向で検討する方が良いと思います。

スキルアップ/キャリアアップ(JOB@IT)