C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: 定時に動作するWindowsサービスの作り方について


(過去ログ 29 を表示中)

[トピック内 15 記事 (1 - 15 表示)]  << 0 >>

■13686 / inTopicNo.1)  定時に動作するWindowsサービスの作り方について
  
□投稿者/ natural (1回)-(2008/02/01(Fri) 16:39:42)

分類:[C#] 

開発ツール:VisualStudio.net2003
開発言語 :C#


はじめまして。C#を学び始めて半年の、naturalと申します。

決められた日時に動作するWindowsサービスを作成しようとしています。
具体的には、(設定ファイルによって、日時は変わりますが)
・毎日2:00に、特定フォルダにあるCSVファイルからデータを取得して、DBへデータ挿入
・毎月1日の0:00に、DBのあるテーブルに書かれているメールアドレスにメール(定型文)を出す。
という2本立てを、1つのWindowsサービスで実現させよう、というものです。

今までに、System.Timers.Timerを使用して、数分間隔ごとに動作を行うサービスは作成したことがあるのですが、
決められた時間になったら動作する、というものは作成したことがありません。

TimerかSleepで数秒or数分置きに現在時刻を確認し、
決められた時刻であった場合、ワーカースレッドを作成して動作させる・・・というような設計を考えたのですが、
みなさんならば、どのような設計・実装方法にしますでしょうか?

皆さんのご意見をお聞かせいただけたら、とてもありがたいです。
よろしくお願いいたします。
引用返信 編集キー/
■13687 / inTopicNo.2)  Re[1]: 定時に動作するWindowsサービスの作り方について
□投稿者/ 774RR (131回)-(2008/02/01(Fri) 16:47:25)
本質的に「サービス」である必然があるのであれば別だが
タスクスケジューラ+非サービスアプリ(通常 Windows アプリ)
の構成を推奨したい
引用返信 編集キー/
■13690 / inTopicNo.3)  Re[2]: 定時に動作するWindowsサービスの作り方について
□投稿者/ natural (2回)-(2008/02/01(Fri) 17:09:29)
No13687 (774RR さん) に返信
回答ありがとうございます。

> 本質的に「サービス」である必然があるのであれば別だが
> タスクスケジューラ+非サービスアプリ(通常 Windows アプリ)
> の構成を推奨したい
上記に書き漏らしておりましたが、
『決められた時間』ですが、これはDBのとあるテーブルから読み出すものなので、
その値次第で、時刻が変わるものです。

なので、Windowsサービスを考えていたのですが・・・いかがでしょうか?
引用返信 編集キー/
■13697 / inTopicNo.4)  Re[3]: 定時に動作するWindowsサービスの作り方について
□投稿者/ れい (411回)-(2008/02/01(Fri) 18:46:49)
No13690 (natural さん) に返信
> 『決められた時間』ですが、これはDBのとあるテーブルから読み出すものなので、
> その値次第で、時刻が変わるものです。

なら、

> TimerかSleepで数秒or数分置きに現在時刻を確認し、
> 決められた時刻であった場合、ワーカースレッドを作成して動作させる・・・というような設計を考えたのですが、
> みなさんならば、どのような設計・実装方法にしますでしょうか?

Timerは大体そんな感じで
よいと思います。

スレッドをどのようにするのかはいろいろ考慮する必要があると思います。

引用返信 編集キー/
■13701 / inTopicNo.5)  Re[3]: 定時に動作するWindowsサービスの作り方について
□投稿者/ やじゅ (83回)-(2008/02/01(Fri) 19:46:09)
No13690 (natural さん) に返信
> ■No13687 (774RR さん) に返信
> 回答ありがとうございます。
>
>>本質的に「サービス」である必然があるのであれば別だが
>>タスクスケジューラ+非サービスアプリ(通常 Windows アプリ)
>>の構成を推奨したい
> 上記に書き漏らしておりましたが、
> 『決められた時間』ですが、これはDBのとあるテーブルから読み出すものなので、
> その値次第で、時刻が変わるものです。
>
> なので、Windowsサービスを考えていたのですが・・・いかがでしょうか?

『決められた時間』も頻繁に変わるとも思われないので、
DBから時刻を読取りタスクスケジューラに自動登録する
アプリケーションを作成すればいいと思います。
上記PGもタスクスケジューラに登録するのもありかと

タスク・スケジューラをコマンド・プロンプトから制御する
http://www.atmarkit.co.jp/fwin2k/win2ktips/582schtasks/schtasks.html
http://nofx2.txt-nifty.com/it/2005/06/post_17d2.html
引用返信 編集キー/
■13703 / inTopicNo.6)  Re[1]: 定時に動作するWindowsサービスの作り方について
□投稿者/ 七曜 (69回)-(2008/02/01(Fri) 20:33:56)
No13686 (natural さん) に返信
> 開発ツール:VisualStudio.net2003
> 開発言語 :C#

.NET 2.0のドキュメントですが・・・考え方とか実装とかは、大きく変わっていないはずなので。

[Windows サービス アプリケーション]
http://msdn2.microsoft.com/ja-jp/library/y817hyb6(VS.80).aspx

"Windows サービス"として作成する場合、ちょっとお作法があるので面倒だったりします。

引用返信 編集キー/
■13771 / inTopicNo.7)  Re[2]: 定時に動作するWindowsサービスの作り方について
□投稿者/ natural (3回)-(2008/02/04(Mon) 18:52:40)
皆様、回答ありがとうございます。
お礼が遅れてしまい、ごめんなさい。

No13697 (れい さん) に返信
> Timerは大体そんな感じで
> よいと思います。
ありがとうございます。
この方法で試してみようと思います。

> スレッドをどのようにするのかはいろいろ考慮する必要があると思います。
2つの処理を、それぞれ1スレッドずつのみ動作するように作成しようと思っています。
(1日〜数日に一回ずつしか動作しないものなので、動作がかぶることはないと思うのですが)
例えばCSVを読み込んでDBへ・・・と動作しているうちに次のCSV読み込み動作が始まって・・・
とマルチスレッドで処理できるほど、私の頭は賢くできていない(理解できていない)ためです。
それぞれ1スレッドで動作し、2つの処理は同じ変数を参照・変更しないのであれば、
特に難しい問題はないと思っているのですが、いかがでしょうか?

No13701 (やじゅ さん) に返信
> 『決められた時間』も頻繁に変わるとも思われないので、
> DBから時刻を読取りタスクスケジューラに自動登録する
> アプリケーションを作成すればいいと思います。
> 上記PGもタスクスケジューラに登録するのもありかと
>
> タスク・スケジューラをコマンド・プロンプトから制御する
> http://www.atmarkit.co.jp/fwin2k/win2ktips/582schtasks/schtasks.html
> http://nofx2.txt-nifty.com/it/2005/06/post_17d2.html
情報ありがとうございます。
タスクスケジューラでの動作で考えたほうが、無難なのでしょうか?
今回は、上司よりWindowsサービスで設計するよう指示がでているため、
なんとかWindowsサービスで・・・と思っているのですが、
こちらも勉強してみたいと思います。
情報ありがとうございます!

No13703 (七曜 さん) に返信
> .NET 2.0のドキュメントですが・・・考え方とか実装とかは、大きく変わっていないはずなので。
>
> [Windows サービス アプリケーション]
> http://msdn2.microsoft.com/ja-jp/library/y817hyb6(VS.80).aspx
>
> "Windows サービス"として作成する場合、ちょっとお作法があるので面倒だったりします。
ありがとうございます。
Windowsサービスについても、まだまだわからないことだらけなので、
上記サイトで勉強します。
ということで一応おおまかに読んでみたのですが、「ちょっとお作法」というのは、
どのことを指していらっしゃるのでしょうか?
よろしければ教えてください。よろしくお願いいたします。
引用返信 編集キー/
■13772 / inTopicNo.8)  Re[3]: 定時に動作するWindowsサービスの作り方について
□投稿者/ natural (4回)-(2008/02/04(Mon) 18:55:50)
追加ですみません。

Timerクラスは、設定した数分おきにイベントを発生させるクラスですが、
・指定した時刻にイベントを発生させる
というようなクラスはないものなのでしょうか?

(googleで、「c# 指定日時」「c# 指定時刻」などと検索しても見つけることができませんでした)
引用返信 編集キー/
■13776 / inTopicNo.9)  Re[4]: 定時に動作するWindowsサービスの作り方について
□投稿者/ はつね (427回)-(2008/02/04(Mon) 19:37:04)
はつね さんの Web サイト
No13772 (natural さん) に返信
> Timerクラスは、設定した数分おきにイベントを発生させるクラスですが、
> ・指定した時刻にイベントを発生させる
> というようなクラスはないものなのでしょうか?

.NET Frameworkにはないはず。

引用返信 編集キー/
■13778 / inTopicNo.10)  Re[3]: 定時に動作するWindowsサービスの作り方について
□投稿者/ やじゅ (94回)-(2008/02/04(Mon) 20:40:02)
やじゅ さんの Web サイト
2008/02/05(Tue) 00:51:28 編集(投稿者)

No13771 (natural さん) に返信
> タスクスケジューラでの動作で考えたほうが、無難なのでしょうか?
> 今回は、上司よりWindowsサービスで設計するよう指示がでているため、
> なんとかWindowsサービスで・・・と思っているのですが、
>

無理にサービスにする必要もないと思いますが…
簡単に確実に実装できるなら、タスクスケジューラで十分な気がします。
その上司に本当にサービスであるべきか再度聞いてみては?

と思ったけど、昔よりサービス作るの簡単になったのねん
じゃーどうでもいいや。
引用返信 編集キー/
■13790 / inTopicNo.11)  Re[3]: 定時に動作するWindowsサービスの作り方について
□投稿者/ れい (415回)-(2008/02/04(Mon) 23:43:43)
No13771 (natural さん) に返信
>>スレッドをどのようにするのかはいろいろ考慮する必要があると思います。
> 2つの処理を、それぞれ1スレッドずつのみ動作するように作成しようと思っています。
> (1日〜数日に一回ずつしか動作しないものなので、動作がかぶることはないと思うのですが)
> 例えばCSVを読み込んでDBへ・・・と動作しているうちに次のCSV読み込み動作が始まって・・・
> とマルチスレッドで処理できるほど、私の頭は賢くできていない(理解できていない)ためです。
> それぞれ1スレッドで動作し、2つの処理は同じ変数を参照・変更しないのであれば、
> 特に難しい問題はないと思っているのですが、いかがでしょうか?

スレッドを分けるかどうかはどのくらい重い処理なのかなどに依ります。
今回は簡単な処理にみえますから、
ワーカースレッドなど作らなくてもTimerCallbackを実行するスレッドで実行すればいいと思います。

また、動作が被ることは考えづらくても、私なら排他処理はしておきます。
何かの都合で処理が詰まっちゃったときなどに困ります。

被る可能性が低いなら、排他の粒度をあげてもいいので簡単です。
例えば、あるメソッド全体を排他的にするなら

private Int32 exclusiveflag = 0;
private void method1() {
if (InterLocked.CompareExchange(ref exclusiveflag, 1, 0) != 0) return;
try {
//処理をここに。
} finally {
InterLocked.Exchange(ref exclusiveflag, 0);
}
}
という感じにすればよく、
今回は処理ごとにメソッドを用意してそれを排他的にすればいいので
かなり簡単です。

> 今回は、上司よりWindowsサービスで設計するよう指示がでているため、
> なんとかWindowsサービスで・・・と思っているのですが、

サービスでもタスクマネージャでも十分に要望は満たせますし、それほど手間も変わりません。
「タスクマネージャに登録するアプリ」と「実際に処理をするアプリ」の二つを作るのはめんどくさいので
私ならサービスにするかな。
引用返信 編集キー/
■13833 / inTopicNo.12)  Re[4]: 定時に動作するWindowsサービスの作り方について
□投稿者/ natural (5回)-(2008/02/05(Tue) 15:34:22)
No13776 (はつね さん) に返信
>>・指定した時刻にイベントを発生させる
>>というようなクラスはないものなのでしょうか?
>
> .NET Frameworkにはないはず。

やはりないんですね。情報ありがとうございます。
タスクスケジューラで実現できるから・・・なのでしょうかね。

No13778 (やじゅ さん) に返信
> 無理にサービスにする必要もないと思いますが…
> 簡単に確実に実装できるなら、タスクスケジューラで十分な気がします。
> その上司に本当にサービスであるべきか再度聞いてみては?
やじゅさんのご意見はもっともだな、と思い、
上司を説得するために、schtasksコマンドについて(まだ少しだけ・・・ですが)勉強してみました。

勉強しているうちに、重要な情報を書き漏らしていたことに気がついたのですが、
今回作成するアプリケーションの稼動環境のOSが、
Windows2000ServerSP4
でした。
shetasksコマンドって、XP Proffesioal以降のOSから対応しているコマンドなんですね。
2000ではatコマンドを使用するようになっているようなので、
このコマンドを使うことで仕様を満たせるかどうか調べてみようと思います。

・・・と、手元にある「Windows DOS/コマンドプロンプト辞典」を見ながら書きかけたのですが、
ネットで調べるかぎり、2000以降から対応しているようですね。
その辺も含めて再調査してみます。


> と思ったけど、昔よりサービス作るの簡単になったのねん
> じゃーどうでもいいや。
以前はもっと大変だったのですね。
初心者の私からしてみれば、今のでも結構大変だなぁと思うのですが(苦笑)
アドバイスありがとうございます。

No13790 (れい さん) に返信
> スレッドを分けるかどうかはどのくらい重い処理なのかなどに依ります。
> 今回は簡単な処理にみえますから、
> ワーカースレッドなど作らなくてもTimerCallbackを実行するスレッドで実行すればいいと思います。
>
> また、動作が被ることは考えづらくても、私なら排他処理はしておきます。
> 何かの都合で処理が詰まっちゃったときなどに困ります。
今回の、CVS読込み→DB挿入程度の処理であれば、それぞれスレッド分けしなくとも
特に問題はなさそうだ、ということですね。

ただ、こちらに質問をさせていただいた後に、
(同じような処理ですが)別々の設定時間に動作する4〜5個の処理が追加になりそうな話になっているので、
スレッド分けしようかどうか迷い中です。
まずは仕様をはっきりさせてみて考えたいと思います。

> private Int32 exclusiveflag = 0;
> private void method1() {
> if (InterLocked.CompareExchange(ref exclusiveflag, 1, 0) != 0) return;
> try {
> //処理をここに。
> } finally {
> InterLocked.Exchange(ref exclusiveflag, 0);
> }
> }
> という感じにすればよく、
> 今回は処理ごとにメソッドを用意してそれを排他的にすればいいので
> かなり簡単です。
InterLockedクラスを使用すれば、別々のスレッドからでも
安全に変数を変更できるんですね。ありがとうございます。

もしもワーカースレッドを作成して処理を行わせるようにした場合なんですが、
例えばA・Bの処理があるとして、Aのワーカースレッドが既に作成されて処理が始まっているかどうかを、
Interlocked.Exchenge()で上記のように判断を行えば、排他処理ができますよね?

> サービスでもタスクマネージャでも十分に要望は満たせますし、それほど手間も変わりません。
> 「タスクマネージャに登録するアプリ」と「実際に処理をするアプリ」の二つを作るのはめんどくさいので
> 私ならサービスにするかな。
色々な考え方があるんですね。
参考にさせていただきます。ありがとうございます。
引用返信 編集キー/
■13836 / inTopicNo.13)  Re[5]: 定時に動作するWindowsサービスの作り方について
□投稿者/ れい (417回)-(2008/02/05(Tue) 16:01:58)
No13833 (natural さん) に返信
> もしもワーカースレッドを作成して処理を行わせるようにした場合なんですが、
> 例えばA・Bの処理があるとして、Aのワーカースレッドが既に作成されて処理が始まっているかどうかを、
> Interlocked.Exchenge()で上記のように判断を行えば、排他処理ができますよね?

たくさんスレッドがあるなら他にもいろいろ手があります。
一番簡単な方法ってだけです。

引用返信 編集キー/
■13839 / inTopicNo.14)  Re[6]: 定時に動作するWindowsサービスの作り方について
□投稿者/ natural (6回)-(2008/02/05(Tue) 16:32:28)
No13836 (れい さん) に返信
> たくさんスレッドがあるなら他にもいろいろ手があります。
> 一番簡単な方法ってだけです。
な、なるほど。調べてみます!
引用返信 編集キー/
■13858 / inTopicNo.15)  Re[3]: 定時に動作するWindowsサービスの作り方について
□投稿者/ 七曜 (71回)-(2008/02/05(Tue) 18:41:11)
No13771 (natural さん) に返信
> ということで一応おおまかに読んでみたのですが、「ちょっとお作法」というのは、
> どのことを指していらっしゃるのでしょうか?
> よろしければ教えてください。よろしくお願いいたします。

・サービス マネージャとのやりとり
・サービスのインストール
・イベントログへの出力
なんかだったかな。あとは、開始や停止(実装していれば、一時停止や再開)なども
たしか、30秒以内に完了しないとサービスマネージャはエラーと判断したような・・・。
ServiceBaseから派生して、必要なプロパティ設定とハンドラを実装していれば(ここら辺をお作法と言っています)、
大体動きますがサービス マネージャ(OSの一部)から監視されるプロセスになる、という点は考慮しておいた方が良いでしょうね。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -