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

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

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

Re[5]: COMコンポーネントを違うアパートメントからアクセスしたい


(過去ログ 63 を表示中)

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

■36516 / inTopicNo.1)  COMコンポーネントを違うアパートメントからアクセスしたい
  
□投稿者/ ヨーキー (7回)-(2009/05/30(Sat) 14:28:51)

分類:[VB.NET/VB2005 以降] 

こんにちは。何度も掲示板をお借りして申し訳ありません。
表題の件について質問させてください。

開発環境:VisualBasic2008 Express Edition
OS:windowsXP
ブラウザ:InternetExplorer8

参照設定:Microsoft HTML Object Library 4.0(COM)
     Microsoft Internet Controls 1.1(COM)

複数起動されたIEより、リアルタイムで更新されるDocumentの情報を取得するプログラムを下記のような構造で作成しております。

クラス構成
windows.forms → クラスA → インターフェース → クラス@(サイト1用) →COM参照
                               → クラスA(サイト2用) →COM参照
                               → クラスB(サイト3用) →COM参照

クラス@〜Bでは、COMオブジェクトを作成し、BackgroundWorkerにて一定間隔でIEのDocument参照し、
更新されていればクラスAにイベント通知するような方法をとっております。
そこで分からないのが、BackgroundWorker(別のアパートメント)からCOMにアクセスする時に、
マーシャリングのエラーを回避するべく メインスレッドにて処理させるようにInvokeしようと考えたのですが、
クラス@〜Bは独自クラスの為にInvokeメソッドを実装しておらず、どうしたらいいか分からず悩んでおります。

そもそもこの考え方自体が間違っているのかもしれませんが、お気づきになることがありましたら教えていただけないでしょうか。。。




引用返信 編集キー/
■36517 / inTopicNo.2)  Re[1]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ 渋木宏明(ひどり) (1169回)-(2009/05/30(Sat) 15:22:48)
渋木宏明(ひどり) さんの Web サイト
> そもそもこの考え方自体が間違っているのかもしれませんが、お気づきになることがありましたら教えていただけないでしょうか。。。

ちゃんとマーシャリングするか、自分で STA なスレッドを作って、その中で IE, HtmlDocument に対する操作を完結させるか、でしょう。



引用返信 編集キー/
■36525 / inTopicNo.3)  Re[2]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ ヨーキー (8回)-(2009/05/30(Sat) 21:23:47)
ご回答ありがとうございますっ!

> ちゃんとマーシャリングするか、自分で STA なスレッドを作って、その中で IE, HtmlDocument に対する操作を完結させるか、でしょう。

やはりそここなんですね(´・ω・`)
マーシャリングについてはいろいろ調べているのですが、具体的にどんなコードを生成すればいいかわからず、書籍を購入してじっくり勉強したいと思います。
リンクまで貼っていただいたのに、申し訳ないです。。。

ハードルの低そうな自分でSTAなスレッドを作る方法を試してみたいと思っているのですが、
HtmlDocumentを読み込むクラス(クラス@〜B)の中でそれぞれThreadクラスを使用して、
スレッド維持しつづけるは問題ありますでしょうか。

と言いますのは、作成しているプログラムは常時経常するタイプで、HtmlDocumentを読み込むクラスは接続するサイト数に応じて増えていくため、最大で10スレッドくらい必要と考えております。
また各サイトはAJAXやFLASHにより、数百ms〜1s間隔で情報更新されるため、100ms間隔でHtmlDocumentから情報を取得しようと考えており、その度にスレッド(COMコンポーネント)を解放するのはコストが大きくなってしまうのではないと心配しております。
(HtmlDocumentから更新通知を受け取る方法が分からなかったため、このような手段を取っております。)

スレッド数の上限ははCPU当たり25個まで、.NET Framework 2.0以降は250個までに変更!?
のような記事を目にして、HtmlDocumentを読み込むクラス以外でもファイル書き出し等で5個くらいスレッドを使用しているため、スレッドがいっぱいになってデッドロック等の危険性はないかと心配しております。。。

こういった用途のプログラムの場合、どう考えるのがセオリーなのかご意見お聞かせ頂けないでしょうか。
引用返信 編集キー/
■36527 / inTopicNo.4)  Re[3]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ Hongliang (407回)-(2009/05/30(Sat) 22:13:39)
> ハードルの低そうな自分でSTAなスレッドを作る方法を試してみたいと思っているのですが、
> HtmlDocumentを読み込むクラス(クラス@〜B)の中でそれぞれThreadクラスを使用して、
> スレッド維持しつづけるは問題ありますでしょうか。
いいんじゃないですかね。

> スレッド数の上限はCPU当たり25個まで、.NET Framework 2.0以降は250個までに変更!?
> のような記事を目にして、HtmlDocumentを読み込むクラス以外でもファイル書き出し等で5個くらいスレッドを使用しているため、スレッドがいっぱいになってデッドロック等の危険性はないかと心配しております。。。
それはスレッドプールで使用できるワーカースレッドの数でしょう。スレッドプールは Delegate で BeginInvoke や BackgroundWorker、ThreadPool クラスなどで使用されます。
Thread クラスを使って自分でスレッドを生成する分には、制約はメモリぐらいです。
引用返信 編集キー/
■36528 / inTopicNo.5)  Re[4]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ ヨーキー (10回)-(2009/05/30(Sat) 23:33:45)
ご回答ありがとうございますっ!

>>スレッド数の上限はCPU当たり25個まで、.NET Framework 2.0以降は250個までに変更!?
>>のような記事を目にして、HtmlDocumentを読み込むクラス以外でもファイル書き出し等で5個くらいスレッドを使用しているため、スレッドがいっぱいになってデッドロック等の危険性はないかと心配しております。。。
> それはスレッドプールで使用できるワーカースレッドの数でしょう。スレッドプールは Delegate で BeginInvoke や BackgroundWorker、ThreadPool クラスなどで使用されます。
> Thread クラスを使って自分でスレッドを生成する分には、制約はメモリぐらいです。

なるほど。誤認識をしておりました。さっそくThreadクラスに挑戦してみます。
手取り足とりありがとうございます〜。
引用返信 編集キー/
■36530 / inTopicNo.6)  Re[3]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ 渋木宏明(ひどり) (1171回)-(2009/05/31(Sun) 01:21:00)
渋木宏明(ひどり) さんの Web サイト
> マーシャリングについてはいろいろ調べているのですが、具体的にどんなコードを生成すればいいかわからず、書籍を購入してじっくり勉強したいと思います。

BCL には明示的な COM マーシャリングを行う手段が用意されていないので、CoMarshalXXX 系の API を使用します。

引用返信 編集キー/
■36634 / inTopicNo.7)  Re[4]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ ヨーキー (11回)-(2009/06/02(Tue) 20:21:51)
ご回答ありがとうございます。

> BCL には明示的な COM マーシャリングを行う手段が用意されていないので、CoMarshalXXX 系の API を使用します。

教えていただいたキーワードを元に、検索して調べてはいるのですが、未だ一向に進展がありません。。。Orz
書籍も地元の本屋では見つけられませんでした。。。

.NETやCOMを基礎から学びたいと思っているのですが、初心者にお勧めの書籍があれば紹介していただけないでしょうか。
inside OLEなどが有名みたいですが、今の私のレベルじゃ理解できない気がいたします。
引用返信 編集キー/
■36645 / inTopicNo.8)  Re[5]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ Atata!! (1回)-(2009/06/02(Tue) 22:03:08)
Atata!!です。

>>BCL には明示的な COM マーシャリングを行う手段が用意されていないので、CoMarshalXXX 系の API を使用します。

RCW は自動的に COM マーシャリング(アパートメント間も含めて)を行うので、直接 API を使用したとしてもマーシャリングできるとは考えれません。
推測ですが MSHTML 自体が STA 以外のアパートメントに対してスタブを生成しないように実装されているのではないでしょうか。

VC++ でこれと近い環境のコードを書いてみましたが、
この現象(IHTMLDocument2 プロキシの frames プロパティを読み取ると E_NOINTERFACE が返される ≒ RCW が InvalidCastException を発生させる)を
回避することは出来ませんでした。
# VC++2008, Vista SP1(x86)環境


ですので、解決策としては2番目のコメントに書かれている通り
> 自分で STA なスレッドを作って、その中で IE, HtmlDocument に対する操作を完結させる
以外に無いと私は考えています。
引用返信 編集キー/
■36649 / inTopicNo.9)  Re[5]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ 渋木宏明(ひどり) (1173回)-(2009/06/03(Wed) 05:59:30)
渋木宏明(ひどり) さんの Web サイト
> .NETやCOMを基礎から学びたいと思っているのですが、初心者にお勧めの書籍があれば紹介していただけないでしょうか。

記憶にないです。
そもそも COM/OLE の仕組み的な内容を扱っている書籍自体が少ないと思うし。

> inside OLEなどが有名みたいですが、今の私のレベルじゃ理解できない気がいたします。

絶版ですが、おすすめはやはり Inside OLE です。
量は膨大ですが、最初のほうはそんなに難しいことは書かれていません。
一度に全部覚える必要もないので、入手可能なら読んでみては。

MSDN ライブラリにも結構情報はあるんですが、ことごとく英文です。

引用返信 編集キー/
■36650 / inTopicNo.10)  Re[6]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ 渋木宏明(ひどり) (1174回)-(2009/06/03(Wed) 06:01:28)
渋木宏明(ひどり) さんの Web サイト
> RCW は自動的に COM マーシャリング(アパートメント間も含めて)を行うので、直接 API を使用したとしてもマーシャリングできるとは考えれません。

ピンポントで API を使用しないで、プロクシの生成から一貫して COM API を使うんならできそうじゃないですか?

引用返信 編集キー/
■36694 / inTopicNo.11)  Re[7]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ Atata!! (2回)-(2009/06/03(Wed) 21:44:10)
> ピンポントで API を使用しないで、プロクシの生成から一貫して COM API を使うんならできそうじゃないですか?

私の予想
> MSHTML 自体が STA 以外のアパートメントに対してスタブを生成しないように実装されている
が正しいならばプロキシを STA なアパートメントから MTA なアパートメントに
コピーできないはずですので、API を駆使しても無理だと思われます。
ここで言うプロキシのコピーとは CoMarshalInterThreadInterfaceInStream と
CoGetInterfaceAndReleaseStream を使用した普通のマーシャリングのことです。

STA で生成したプロキシを MTA にコピーした場合、プロキシは STA を経由するような動作にはなりません。
MTA のプロキシ ⇒ STA 上に構築されたスタブ ⇒ STA のプロキシ ⇒ オリジナルのスタブ
ではなく
MTA のプロキシ ⇒ オリジナルのスタブ
と経路が短絡されるはずです。(この動作によって DCOM はパフォーマンスを稼いでるはず・・・)
このため MTA に対するスタブの生成を抑制している場合、MTA ではプロキシの生成に失敗するはずです。

# まぁ、DCOM はもっと複雑な処理になっていた気がしますが。
# 前回書くのを忘れてましたが、検証には IE7 を使用しています。


で、上記の内容を現時点で質問者が完全に理解できるとは思えないので、
私が提案できる現実的な解決方法は COM を使用しないことになります。
WebBrowser コントロールを貼り付けた非表示のフォームをスレッド毎に作成して、
メインのフォーム(?)から、それらスレッド上のフォームを操作するように
設計し直した方が良いのではないでしょうか?
引用返信 編集キー/
■36748 / inTopicNo.12)  Re[8]: COMコンポーネントを違うアパートメントからアクセスしたい
□投稿者/ ヨーキー (12回)-(2009/06/04(Thu) 18:38:58)
ご回答ありがとうございます。

教えていただいた、STAなThreadクラスを使う方法で、Frameページへのアクセスは確認できた!
しかし、COMコンポーネントを維持するのにメッセージポンプ?がどうとかって言うエラーが発生しており、
また動作中に強制終了されてしまう不具合が生じております。
ThreadクラスやCOMの扱い方に問題があると予想しているのですが、
まだ勉強しきれておらず、解決できていません(´・ω・`)

> # まぁ、DCOM はもっと複雑な処理になっていた気がしますが。
> # 前回書くのを忘れてましたが、検証には IE7 を使用しています。

検証までして頂いて、本当にありがとうございます。
VBA育ちの私には、基本的な部分が理解できていないようで、、、知識不足を実感しております。

> で、上記の内容を現時点で質問者が完全に理解できるとは思えないので、
> 私が提案できる現実的な解決方法は COM を使用しないことになります。
> WebBrowser コントロールを貼り付けた非表示のフォームをスレッド毎に作成して、
> メインのフォーム(?)から、それらスレッド上のフォームを操作するように
> 設計し直した方が良いのではないでしょうか?

COMを使用しない方法っ!これは新しいw
WebBrowserコントロールの方がネットの記事も多いですし、こちらの方が簡単そうですね!
さっそくテストしてみたいと思います。

話が反れて申し訳ありませんが、WEBサイトの中にはFLASHが埋め込まれいるページがあって、
DOMやAPIなどで埋め込まれているFLASHから情報取得ができないか調べているのですが、
技術的に不可能なのでしょうか。
何かご存知であれば教えていただきたく、お願いいたします。
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -