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

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

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

Re[9]: Windowsサービス内でメッセージループを作る


(過去ログ 38 を表示中)

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

■19451 / inTopicNo.1)  Windowsサービス内でメッセージループを作る
  
□投稿者/ まどか (520回)-(2008/05/23(Fri) 10:48:02)

分類:[.NET 全般] 

#2003Server、Framework3.0、VB.NET2005
TAPIを使用するWindowsサービスを開発しています。
TAPI.DLLを呼び出すVCラッパ+それを呼ぶVBラッパという構成です。

コールバックが発生しない件で、前スレで原因はわかりました。
http://bbs.wankuma.com/index.cgi?mode=al2&namber=19356

で、対処方法としてメッセージループを持たせないといけないのですが。
http://support.microsoft.com/kb/228448/en-us/

具体的にどのような方法になるのでしょうか?
・ServiceMain.OnStartで空のフォームを作る
・VCラッパでMain関数もどきを実装する

現在の実装は、ServiceMain.OnStart→VBラッパNew→VCラッパ→TAPI.InitializeExというように
サービス起動時のスレッドでInitializeExの呼び出しまで到達しています。

感覚的にはなんとなくですが、どこに何をというのがそこまで知識がありません。
ご助言をお願いいたします。
引用返信 編集キー/
■19458 / inTopicNo.2)  Re[1]: Windowsサービス内でメッセージループを作る
□投稿者/ 渋木宏明(ひどり) (762回)-(2008/05/23(Fri) 12:30:13)
渋木宏明(ひどり) さんの Web サイト
> 感覚的にはなんとなくですが、どこに何をというのがそこまで知識がありません。

この場合、基本的には OnStart() でワーカースレッドを起こして、そっちにすべて(Form の new も TAPI 周りもすべて)実装するべきでしょう。

それと、サービスとして動かすとデバッグしにくくなるので、サービス本体は SCM との通信だけに専念して、サービスに組み込むロジックはそれだけで浮かしておいた方が吉です。



引用返信 編集キー/
■19464 / inTopicNo.3)  Re[2]: Windowsサービス内でメッセージループを作る
□投稿者/ まどか (522回)-(2008/05/23(Fri) 14:03:02)
#CでWinアプリを丸ごと作ったことが無いのでかみ合ってない返信をしてるかもしれません。。。

No19458 (渋木宏明(ひどり) さん) に返信
> この場合、基本的には OnStart() でワーカースレッドを起こして、そっちにすべて(Form の new も TAPI 周りもすべて)実装するべきでしょう。

「するべき」とは問題が解決するという意味でしょうか?
#ServiceMainのインスタンスが存在するスレッドだからその問題が起きるという意味?

Windowsサービスでは何もしなきゃメッセージループなんて無いので、自分で作るしかないという認識でよいでしょうか?
#であれば「Form の new も 」はウィンドウハンドルを作れということですよね?

> それと、サービスとして動かすとデバッグしにくくなるので、サービス本体は SCM との通信だけに専念して、サービスに組み込むロジックはそれだけで浮かしておいた方が吉です。

これはクラス構成の話でしょうか?
それとも、
#現状はOnStartで必要なクラスのNewが並んでいるだけである意味ロジックは無いのですが、
先のお話のように別のスレッドを作れということでしょうか?
引用返信 編集キー/
■19476 / inTopicNo.4)  Re[3]: Windowsサービス内でメッセージループを作る
□投稿者/ 渋木宏明(ひどり) (763回)-(2008/05/23(Fri) 15:56:39)
渋木宏明(ひどり) さんの Web サイト
2008/05/23(Fri) 16:18:49 編集(投稿者)

> Windowsサービスでは何もしなきゃメッセージループなんて無いので、自分で作るしかないという認識でよいでしょうか?

メッセージループどころか、原則として SCM に呼びかけられない限り何も実行されません。

定期的に何か処理を実行する必要があるなら、タイマ仕掛けたり、ワーカースレッドを起動します。

OnStart() で直にメッセージループなんか回した日には、SCM に「応答がない」つって強制終了されちゃうはず。

そんなわけで、メッセージループを回したいのであれば、ワーカースレッドの起動は必須です。

> #であれば「Form の new も 」はウィンドウハンドルを作れということですよね?

別スレッドでメッセージループを回すなら、そのスレッドコンテキストで Form のインスタンスを作らないとダメ、という話です。

また、必ずしも Form のインスタンスを new しただけでウィンドウハンドルが作成されるわけではありませんが、Form の実装次第で Show() する以前にウィンドウハンドルが生成されることがあり得ます。

ウィンドウハンドルはそのウィンドウハンドルを生成したスレッドと関連付けられ、そのスレッドで回したメッセージループからメッセージのディスパッチを受けます。

なので、総合すると、ワーカースレッドでメッセージループを回すのなら、Form のインスタンス生成からワーカースレッドで行うのが無難なのです。

なお、TAPI とどういうやりとりをしているのか知らないので、Form のインスタンスが必要なのかどうかまでは分かりません。

ひょっとしたら、ウィンドウレスでメッセージループを回すだけでもいいのかもしれませんが。



引用返信 編集キー/
■19483 / inTopicNo.5)  Re[4]: Windowsサービス内でメッセージループを作る
□投稿者/ まどか (526回)-(2008/05/23(Fri) 16:51:05)
No19476 (渋木宏明(ひどり) さん) に返信
> また、必ずしも Form のインスタンスを new しただけでウィンドウハンドルが作成されるわけではありませんが、Form の実装次第で Show() する以前にウィンドウハンドルが生成されることがあり得ます。

これについては、Handleプロパティが参照した時点で未作成ならその場で作成されるという挙動なので、ダミー代入文を書けば解決できますね。

> なので、総合すると、ワーカースレッドでメッセージループを回すのなら、Form のインスタンス生成からワーカースレッドで行うのが無難なのです。

たとえば、ServiceMainにある変数と処理を丸々クラス化し、OnStartでそのインスタンスを作成してThread.Startで呼び出す。
そしてその呼び出されるプロシージャがメッセージループ本体ということでいいですか?

仕組みとしては、TAPI起点のコールバックを受けて各機能が動きます。
したがって、OnStartでは各機能のインスタンスを作っているだけです。
引用返信 編集キー/
■19500 / inTopicNo.6)  Re[5]: Windowsサービス内でメッセージループを作る
□投稿者/ 渋木宏明(ひどり) (764回)-(2008/05/23(Fri) 21:13:27)
渋木宏明(ひどり) さんの Web サイト
> これについては、Handleプロパティが参照した時点で未作成ならその場で作成されるという挙動なので、ダミー代入文を書けば解決できますね。

自分が参照してなくても、Form の上に乗っけた何かが参照しているかもしれません。
まぁ、その辺の管理に自信があるなら問題無いでしょう。

> たとえば、ServiceMainにある変数と処理を丸々クラス化し、OnStartでそのインスタンスを作成してThread.Startで呼び出す。
> そしてその呼び出されるプロシージャがメッセージループ本体ということでいいですか?

そゆことです。
そーすれば、その「丸々クラス化」した部分だけをユニットテストすることも可能になるなどの利点があります。

引用返信 編集キー/
■19503 / inTopicNo.7)  Re[6]: Windowsサービス内でメッセージループを作る
□投稿者/ まどか (530回)-(2008/05/23(Fri) 22:36:39)
No19500 (渋木宏明(ひどり) さん) に返信
> まぁ、その辺の管理に自信があるなら問題無いでしょう。

これについては、MSDNに明記されていますので。


実際の実装については他のメンバとの話で先が見えてきた感じです。
ありがとうございました。
解決済み
引用返信 編集キー/
■19510 / inTopicNo.8)  Re[7]: Windowsサービス内でメッセージループを作る
□投稿者/ Azulean (120回)-(2008/05/24(Sat) 00:06:13)
>>まぁ、その辺の管理に自信があるなら問題無いでしょう。
> これについては、MSDNに明記されていますので。
「これ」の指すものが気になりました。
どこまでが明記されているのでしょうか?

推測
「Handleプロパティが参照されない限りウィンドウは作成されない」がMSDNに明記されているから大丈夫と解釈し、また、Formには何も貼り付けてないから大丈夫という解釈?
解決済み
引用返信 編集キー/
■19527 / inTopicNo.9)  Re[8]: Windowsサービス内でメッセージループを作る
□投稿者/ まどか (531回)-(2008/05/24(Sat) 20:44:08)
No19510 (Azulean さん) に返信
> 「これ」の指すものが気になりました。
> どこまでが明記されているのでしょうか?

ひどりさんの
> 必ずしも Form のインスタンスを new しただけでウィンドウハンドルが作成されるわけではありませんが
に対してです。

解説に明記されています。
http://msdn.microsoft.com/ja-jp/library/system.windows.forms.control.handle(VS.80).aspx

もし、Newとx = form,Handleの連続ステップというやり方で効力が無いなら改めなければいけませんが。。。
解決済み
引用返信 編集キー/
■19538 / inTopicNo.10)  Re[9]: Windowsサービス内でメッセージループを作る
□投稿者/ Azulean (122回)-(2008/05/25(Sun) 01:40:05)
> ひどりさんの
>>必ずしも Form のインスタンスを new しただけでウィンドウハンドルが作成されるわけではありませんが
> に対してです。

> もし、Newとx = form,Handleの連続ステップというやり方で効力が無いなら改めなければいけませんが。。。

なるほど。
大本の文章の意図を読み違えていたようですみません。

昨日に投稿した時点では、newだけを "OnStartが実行されるスレッド" で先にやりたいという風に読んでいました。
この前提では、New(もといコンストラクタ)で実行されるInitializeComponentのコードとその先で呼び出されるコードにより、Newの時点でHandleが作成される恐れがあるという懸念を持ち、昨日あのように質問してみたものです。


----- 以下は2つの手法について考えたもの。本筋の質問とは外れてます。

A.Handleプロパティを参照して値を捨てる。(静的コード分析では不要なコードと指摘される恐れがあるかどうか?)
B.IsHandleCreatedプロパティを参照して、場合によってはCreateControl(CreateHandle?)メソッドを呼び出す。

(見える範囲のコードでは)Aの方が条件分岐がなくてすっきりしているように見えるが、本来の目的はBのようなことであり、Handleプロパティの既定の実装がそれらを内部に隠してくれている。
どちらを使うかは、実害がない限り、好みの問題となるかなぁ。
解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -