酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows PhoneでHttpWebRequest/HttpWebResponseを使ってWebページを取得する

概要

HttpWebRequestとHttpWebResponseは、.NET FrameworkでHTTP通信させるのに定番のクラスです。

Windows Phone(Silverlightプラットフォーム)では、UIスレッドを停止させるような「通信」という重い処理をUIスレッド上で同期的に扱うことが出来ません。BeginXXXで始まってEndXXXで終わるIAsyncResultパターンで実装ひとつひとつ実装させるのも良いのですが、通信が入れ子になった場合コードの実装量が増え可読性を大きく損なってしまいます。

Tips

Webページを取得する

Webページを取得するためには、WebClientクラスのほかにHttpWebRequestクラスが使うことが出来ます。

Windows Phone(Silverlight)では、UIスレッド上で通信など"重い処理"を行うのを嫌います。WebClientクラスはリソースの取得完了をイベントで通知してくれ大変便利なのですが、ここではHttpWebRequestクラスとHttpWebResponseクラスを使ってみましょう。

Windows Phoneでは基本非同期APIしかサポートされていませんので、非同期処理を簡単に制御出来るようにReactive Extention(Rx)というフレームワークを使用します。

Reactive Extentionを使うには、Microsoft.Phone.ReactiveとSystem.Observableを参照しておく必要があります。ソリューションエクスプローラーから該当のプロジェクトを右クリックし、参照の追加を選択します。

f:id:ch3cooh393:20141117222331p:plain

WebRequest.CreateHttpメソッドで、リクエストオブジェクトを作成します。ここまでは普通の処理です。

Observable.FromAsyncPatternを起点にして、非同期処理が開始され、Selectメソッドでレスポンスストリームから文字列を呼び出して、ObserveOnDispatcherメソッドでUIスレッドに処理を戻します。これ以降は、UIスレッド上の処理になりますので、MessageBox.Showでメッセージを表示しています。

//using System.Net;
//using Microsoft.Phone.Reactive;
//using System;
//using System.IO;

var uri = new Uri("http://search.twitter.com/search.atom?q=ch3cooh");
var req = WebRequest.CreateHttp(uri);

// IAsyncResultパターンの非同期動作をラッピング
Observable.FromAsyncPattern<WebResponse>(req.BeginGetResponse, req.EndGetResponse)()
 .Select(res => new System.IO.StreamReader(res.GetResponseStream()).ReadToEnd())
 .ObserveOnDispatcher()
 .Subscribe(msg => MessageBox.Show(msg));