Visual C#のWebBrowser、HtmlDocument、HtmlElementコンポーネント関連とApplication.DoEvents();のメモ書きです。

下のソースでは以下の作業をしています。
①適当なhtml情報をWebBrowserコンポーネント(webBrowser1)のDocumentTextプロパティにセットする
②webBrowser1のDocumentプロパティからHtmlDocumentコンポーネント(hDocument )を作成
③hDocumentのBodyプロパティからHtmlElement コンポーネント(hBody )を作成

//①
webBrowser1.DocumentText = "html情報";
//②
HtmlDocument hDocument = webBrowser1.Document;
//Ⅰ
Application.DoEvents();
//③
HtmlElement hBody = hDocument.Body;
//Ⅱ
while (hBody == null)
{
System.Threading.Thread.Sleep(5);
Application.DoEvents();
hBody = hDocument.Body;
}

ただ、この三行のコードだけだと"html情報"が正常にセットできてないみたいなのでApplication.DoEvents();を入れてみました。

(Application.DoEvents();はwindowsアプリのメッセージキューにたまったすべてのWindowsメッセージを処理します。)

上のコードでは、ⅠのApplication.DoEvents();を実行する前はwebBrowser1.DocumentTextは"html情報"文字列にセットされてないし、hDocumentのBodyプロパティもnullのままですが、ⅠのApplication.DoEvents(); を実行後はwebBrowser1.DocumentTextもhDocumentのBodyプロパティは正しくセットされています。

Ⅱの部分もwhileループの初回条件時にHtmlElementのhBodyがnullのままになっていることがあるのでループの中でApplication.DoEvents(); を実行し、もう一度hBodyにセットしなおし、ループの条件でもう一度nullかどうか確認しています。SleepはwhileループがなんどもループするとCPU占有率が高くなってしまうのでそれを防ぐためです。
(このループだと無限ループに陥りそうでちょっと不安ではあります。実際に使う時は、まぁループ回数に制限を設けるなり、ループ内でbreak文を追加するなりした方がいいかもしれません。)

ただ、自分でサンプルコードを書いておいてなんですが、上のコードだとApplication.DoEvents();が何故必要なのか?というより Application.DoEvents();を書かなくても処理してくれよと思ってしまい正直まだしっくりきません・・・

Application.DoEvents()はこの例以外にもWebBrowserがNavigate()メソッドでウェブページを取得完了を待つときにも使われます。

お安いレッツノートPCをネットで購入する!
100000円以下のお安いおすすめノートPC(let's noteシリーズ)をネットで購入!
格安・激安のLet's noteシリーズ(パナソニック)ノートパソコン情報

仕事ができる人はなぜレッツノートを使っているのか?/山田 祥平
¥1,575
Amazon.co.jp



・C#入門者のためのおすすめ入門本

JIS規格対応 標準C#入門 改訂第2版/矢沢 久雄
¥2,835
Amazon.co.jp



・ネットワークの基本HTTPプロトコルのおすすめ入門書籍の紹介

今夜わかるHTTP (Network)/上野 宣
¥2,520
Amazon.co.jp



参考サイト
時間がかかる処理での「応答なし」を回避するには?
HTML内のRSS情報を取得する
WebBrowserコントロールによりWebページからリンクや画像を抽出するには?
MSDN Application.DoEvents
C#で覚えるウィンドウズプログラミング 社内勉強会