• Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
No Downloads

Views

Total Views
2,786
On Slideshare
0
From Embeds
0
Number of Embeds
1

Actions

Shares
Downloads
19
Comments
0
Likes
1

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 実践 Reactive Extensions 2011/08/27 Silverlight/Phone Quest I 伊勢 シン (Microsoft MVP for Windows Phone)
  • 2. 自己紹介• 伊勢 シン – Microsoft MVP for Windows Phone (Oct 2010-Sep 2011)• 大阪で働くスマートフォンプログラマ – 目指すは「スマートフォンの万屋」 – iOSアプリをビルドをしながらAndroidアプリのコーディングやったりとか – Windows Phone 7 も少々• 趣味もスマートフォンアプリ開発で – EbIRC – SongTweeter• コミュニティ – スマートフォン勉強会 代表 – Windows Phone Arch 関西スタッフ?
  • 3. おしながき• Reactive Extension について – 基本的なこと – 書き方の考え方• 実例でみるReactive Extensions – RSSの取得 – ログインが必要なページの先からファイルダウンロード – 複数ページをダウンロードして一括処理 – なんでもいいからとにかく非同期
  • 4. Reactive Extensions について
  • 5. そもそもReactive Extensionsって何ぞ• Reactive Extensions (Rx)• LINQの機能を時間軸に拡張するライブラリ – LINQ to SQL, LINQ to Objects に対する LINQ to Events, LINQ to Asynchronous – “WhereでフィルタしてSelectで射影できるならLINQ といえる” – by @neuecc
  • 6. なにがうれしいの?• 複雑な非同期処理を「直線的に」書ける – 非同期のコードはひたすらネストがつづく – “もはやカオスすぎて頭が痛い” by @neuecc• 例外処理をひとまとめに書ける – Subscribeの第2引数のラムダで一括処理可能• その他各種特典 – 中断処理も簡単。 – リトライ処理 – 処理の待ち合わせ、結合など
  • 7. “もはやカオスすぎて頭が痛い” 例
  • 8. そう、RxならねWebRequest.Create("http://hoge") .GetResponseAsObservable() .Select(res => new StreamReader(res.GetResponseStream()).ReadToEnd()) .SelectMany(s => WebRequest.Create(s).GetResponseAsObservable()) .Select(res => new StreamReader(res.GetResponseStream()).ReadToEnd()) .ObserveOnDispatcher() .Subscribe( s => MessageBox.Show(s), e => MessageBox.Show(e.ToString()));
  • 9. どこでつかえるの?• Windows Phone のクラスライブラリに 標準搭載され、非同期処理しか存在しない Silverlight の存在も相まって注目度アップ• WP7だけでなく、いろいろなところでつかえます – .NET Framework 3.5 / 4 Client Profile – Silverlight 3 / 4 / for Windows Phone – XNA 3.1(Zune) / 4 (Xbox360) – http://www.microsoft.com/download/en/details .aspx?id=24940
  • 10. どうやって使うの?@WP7• 以下のアセンブリを参照 – Microsoft.Phone.Reactive – System.Observable• Rxを使いたいcsファイルのusingに以下を追加 – Microsoft.Phone.Reactive• すべてのはじまりは Observable クラス
  • 11. そもそもマルチスレッドの基本的な考え方UIスレッド トリガー UI反映 スレッド同期どこか別のスレッド 時間のかかる処理 結果の処理
  • 12. Rx コードの基本構成 1.トリガー Observable.FromAsyncPattern<WebResponse>( req.BeginGetResponse, req.EndGetResponse)() .Select(res => XDocument.Load(res.GetResponseStream())) .SelectMany(doc => doc.Element("Categories").Elements("Category")) .Select(elem => new { ID = elem.Element("ID").Value, 2.データ処理 Name = elem.Element("Name").Value }) .ObserveOnDispatcher() 3.スレッド同期 .Subscribe(res => { // UI反映 }, err => { // 例外処理 4.UI反映 });
  • 13. 簡単にRxを書くために• 通信処理系のRxを書くなら RxAsynchronousHelper を使うと便利です。 – 通信を非同期に行うためのRxのおきまり処理を うまくパッケージングしたクラス。あるだけで便利。 – by @neuecc – http://neue.cc/2010/11/26_286.html
  • 14. 実例で見るReactive Extensionsの使い方
  • 15. RSSを受信する• 単純な処理の例 – XDocumentの名前空間つけないといけないのだけ なんとかならんかと思っています。
  • 16. 単純なRSS受信private const string Name_RDF = "{http://www.w3.org/1999/02/22-rdf-syntax-ns#}RDF";private const string Name_Item = "{http://purl.org/rss/1.0/}item";private const string Name_Title = "{http://purl.org/rss/1.0/}title";private const string Name_Link = "{http://purl.org/rss/1.0/}link";var req = WebRequest.CreateHttp("http://d.hatena.ne.jp/iseebi/rss");Observable.FromAsyncPattern<WebResponse>(req.BeginGetResponse, req.EndGetResponse)() .Select(res => XDocument.Load(res.GetResponseStream())) .Select(doc => from elem in doc.Element(Name_RDF).Elements(Name_Item) select new { Title = elem.Element(Name_Title).Value, Link = elem.Element(Name_Link).Value }) .ObserveOnDispatcher() .Subscribe(res => { foreach (var item in res) { Debug.WriteLine("{0} -> {1}", item.Title, item.Link); } });
  • 17. RxAsynchronousHelperを使った場合WebRequest.CreateHttp("http://d.hatena.ne.jp/iseebi/rss") .GetResponseAsObservable() .Select(res => XDocument.Load(res.GetResponseStream())) .Select(doc => from elem in doc.Element(Name_RDF).Elements(Name_Item) select new { Title = elem.Element(Name_Title).Value, Link = elem.Element(Name_Link).Value }) .ObserveOnDispatcher() .Subscribe(res => { foreach (var item in res) { Debug.WriteLine("{0} -> {1}", item.Title, item.Link); } });
  • 18. ダウンロードの結果解析で次のファイルへ• ログインが必要なページなどに有効• SelectManyにすれば、流れに全く関係のない IObservable<T> を新規にメソッドチェーンに 流せる。
  • 19. テキストに書いてあるURLをさらに取得// URLが書いてあるWebRequest.CreateHttp("http://iseebi.half-done.net/test/url.txt") .DownloadStringAsync() // 新しいIObservableを流す .SelectMany(res => WebRequest.CreateHttp(res).DownloadStringAsync()) .ObserveOnDispatcher() .Subscribe(res => { Debug.WriteLine(res); });
  • 20. 一括ダウンロードしてから処理• 複数のファイルをダウンロードし、 ダウンロード完了後に処理したい場合 – 定義ファイルの一括取得など
  • 21. 一括ダウンロード// ダウンロード処理を一括でリストにするvar l = new List<IObservable<string>>(){ WebRequest.CreateHttp("http://iseebi.half-done.net/test/phone.txt").DownloadStringAsync(), WebRequest.CreateHttp("http://iseebi.half-done.net/test/clientappdev.txt").DownloadStringAsync(), WebRequest.CreateHttp("http://iseebi.half-done.net/test/deviceappdev.txt").DownloadStringAsync(), WebRequest.CreateHttp("http://iseebi.half-done.net/test/powershell.txt").DownloadStringAsync(),};// ForkJoinで一括処理Observable.ForkJoin(l) .ObserveOnDispatcher() .Subscribe(res => { foreach (var item in res) { Debug.WriteLine(item); } });
  • 22. なんでもいいからとにかく非同期に• とにかくなんでもいいので非同期にしたい場合、 以下の組み合わせで何もないところから処理を 作り出せる。 – Observable.Defer – Observable.ToAsyncObservable.Defer(Observable.ToAsync(() =>System.Threading.Thread.Sleep(3000))) .ObserveOnDispatcher() .Subscribe(res => Debug.WriteLine("Success!!!"));
  • 23. まとめ• Rx 使うと非同期処理が きれい、かんたん、便利に書けます。 – いくつかの実例をみてご紹介しました。• Special thanks to @neuecc