C#次世代非同期処理概観
Task vs Reactive Extensions

                     2012/3/10 #riaarch
              Yoshifumi Kawai @neuecc
Profile
 Name    => Yoshifumi Kawai
     仕事は近頃はASP.NETで、あまりRIAじゃなかったり
     まあ、HTML5もRIAですし!
 Twitter
        => @neuecc
 HN => neuecc
     読むときは“のいえ”と読ませてます
     サイトのドメイン(特に意味はない)を繋いだだけ
      で、識別子になればそれだけでいいと思って発音考
      えてなかったので割とアレ
     Microsoft MVP for Visual C#(2011/4-)
サイト
 http://neue.cc/
 C#とかLINQ
 配色がアレ
linq.js
 http://linqjs.codeplex.com/
 LINQのJavaScript移植
ReactiveProperty
 http://reactiveproperty.codeplex.com/
 Rxスタイルのバインディング補助ライブラリ
 .NET4/SL5/SL5/WP7.1   対応
Agenda
 非同期処理とは何か
 非同期処理の苦痛
 .NET Frameworkにおける非同期処理パターン
 C# 5.0(Visual Studio 11)の非同期処理(async/await)

 Task   vs Rx
What is asynchronous?
非同期って?
 Parallel?
     並列 - 一つの処理をバラして同時実行して高速化
     Parallel.For/Parallel.ForEach/Parallel LINQ
 Concurrent?
     並行 - 個別な処理が相互作用したりしなかったり
     Thread, Task
 Asynchronous!
     非同期 - ブロックしない処理
     UIスレッドを止めなかったりIO処理効率化だったり
     DownloadStringAsyncなどやBeginXxx-EndXxxなど
     ThreadやTaskを使っても勿論いい
非同期はなぜ重要か
 「クラウド」並のバズワード、とか言ってみたり
 RIA的にはUIスレッドのブロックいくない
    ユーザーエクスペリエンス的には当然だろ常考
    Silverlight, Windows Phone, Windows 8(WinRT)には最
     初から非同期メソッドしか用意されていない(同期
     処理不可!)
    JavaScriptなんて最初からそれOnlyですしね

 Web的には同時接続対策
    C10K問題
        http://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem
    node.jsの流行にC#erとしてはC# 5.0で対抗する!
Demo
Asynchronous Blues
ネスト宇宙ヤバイ
 単発ならそれほどでもない
 ネストすると人類の手に負えない

var wc = new WebClient();
wc.DownloadStringCompleted += (_, res) =>
{
    var wc2 = new WebClient();
    wc2.DownloadStringCompleted += (__, res2) =>
    {
        MessageBox.Show(res2.Result);
    };
    wc2.DownloadStringAsync(new Uri(res.Result));
};

wc.DownloadStringAsync(new
Uri("http://localhost:8403/TestAPI.ashx"));
例外処理不能
 というかもう無理。
var wc = new WebClient();
wc.DownloadStringCompleted += (_, res) =>
{
    if (res.Error != null)
    {
        MessageBox.Show(res.Error.Message);
    }

     var wc2 = new WebClient();
     wc2.DownloadStringCompleted += (__, res2) =>
     {
         if (res2.Error != null)
         {
             MessageBox.Show(res2.Error.Message);
         }

         MessageBox.Show(res2.Result);
     };
     wc2.DownloadStringAsync(new Uri(res.Result));
};

wc.DownloadStringAsync(new Uri("http://localhost:8403/TestAPI.ashx"));
Patterns of Async Operation
APMとは
 Asynchronous Programming Model
 BeginXxx-EndXxxのペアによる非同期処理

 WebRequest#BeginGetResponse-EndGetResponse
 のようなもの

 とにかく面倒くさい
    ラムダ式登場で割と緩和されたけれど
 正しく使うのは慣れが必要
 後述するTaskやRxのベースとして活躍
 .NETにおけるもっともプリミティブな非同期シス
 テムと考えていただければ
var req = WebRequest.Create("http://localhost:8403/TestAPI.ashx");
req.BeginGetResponse(ar =>

                                   非同期処理中の例外はEndのタイミングで伝送
{
    try
    {
        var res = req.EndGetResponse(ar);

       var req2 = WebRequest.Create(new StreamReader(res.GetResponseStream()).ReadToEnd());

       req2.BeginGetResponse(ar2 =>
       {                                              UIスレッドへ通達する必要がある
           try
           {
               var res2 = req2.EndGetResponse(ar2);

               var result = new StreamReader(res2.GetResponseStream()).ReadToEnd();

               Dispatcher.BeginInvoke(() => MessageBox.Show(result));
           }
           catch (Exception ex2)
           {
               Dispatcher.BeginIncoke(()=> MessageBox.Show("inner error " + ex2.Message));
           }
       }, null);
    }
    catch (Exception ex1)         catchできるのは同じ関数のブロック内だけ
    {
        Dispatcher.BeginIncoke(()=> MessageBox.Show("outer error " + ex1.Message));
    }
}, null);
EAPとは
 Event-BasedAsynchronous Pattern
 XxxAsyncメソッド + XxxCompletedイベントのペア
  による非同期処理
 WebClient#DownloadStringAsyncのようなもの


 素の状態のC#では割と楽な書き方
 リクエストの発行が後になるという順序の問題を
  抱える
 後述するTaskやRxの登場でサヨウナラ行き
 TaskやRxでラップするのも面倒くさいという
UIスレッドまわりは自動で面倒
var wc = new WebClient();
wc.DownloadStringCompleted += (_, res) =>      みてくれる(WebClientの場合)
{
    if (res.Error != null)
    {
        MessageBox.Show(res.Error.Message);
    }

     var wc2 = new WebClient();
     wc2.DownloadStringCompleted += (__, res2) =>
     {
         if (res2.Error != null)
         {
                                                    先にイベントを登録して
             MessageBox.Show(res2.Error.Message);
         }

         MessageBox.Show(res2.Result);
     };
     wc2.DownloadStringAsync(new Uri(res.Result));
};

wc.DownloadStringAsync(new Uri("http://localhost:8403/TestAPI.ashx"));




          リクエストの発行は後で行う(順序が逆だとダメ!)
TAPとは
 TaskBased Asynchronous Pattern
 .NET 4/SL5以降登場したTPLを使った非同期処理
     TPLはTask Parallel Libraryの略
     Threadを概ね置き換えます


 Task.Factory.FromAsyncでAPMをラップ
 .NET
   4.5やWinRTにはフレームワークに最初から
 ラップ済み or TAP用に書かれた専用メソッドが大
 量追加
     WebRequest#GetResponseAsyncとか
     WebClient#DownloadStringAsyncとか
UIスレッド用スケジューラを用意することで
                          個別BeginInvoke不要


var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();
                                                                         APMをラップする

var req = WebRequest.Create("http://localhost:8403/TestAPI.ashx");
Task.Factory.FromAsync<WebResponse>(req.BeginGetResponse, req.EndGetResponse, null)
    .ContinueWith(res =>
    {
        var req2 = WebRequest.Create(new StreamReader(res.Result.GetResponseStream()).ReadToEnd());
        return Task.Factory.FromAsync<WebResponse>(req2.BeginGetResponse, req2.EndGetResponse, null);
    })
    .Unwrap()
    .ContinueWith(res =>
                                      ネストしたTaskは明示的にUnwrap
    {
        MessageBox.Show(new StreamReader(res.Result.GetResponseStream()).ReadToEnd());
    }, uiScheduler)
    .ContinueWith(res =>
    {
        MessageBox.Show(res.Exception.Message);
    }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiScheduler);




階層構造はフラット                                           例外は最後に統一的処理が可能
Rxとは
 Reactive   Extensions
     http://msdn.microsoft.com/en-us/devlabs/gg577609
 LINQベースのイベント・非同期処理ライブラリ

 LINQ
     to Events, LINQ to Asynchronous
 WP7には同梱、JavaScript版もあり


 @ITで連載やってるので読んでね!
     http://www.atmarkit.co.jp/fdotnet/introrx/index/index.
      html
 LINQベースのため合成処理が異常なほど強力
 非同期処理だけではなくあらゆる用途に使える
APMをラップする

var req = WebRequest.Create("http://localhost:8403/TestAPI.ashx");

Observable.FromAsyncPattern<WebResponse>(req.BeginGetResponse, req.EndGetResponse)()
    .SelectMany(res =>
    {
        var next = new StreamReader(res.GetResponseStream()).ReadToEnd();
        var req2 = WebRequest.Create(next);
        return Observable.FromAsyncPattern<WebResponse>(req2.BeginGetResponse, req2.EndGetResponse)()
    })
    .ObserveOnDispatcher()      実行スレッドのコントロール
    .Subscribe(
        res => MessageBox.Show(new StreamReader(res.GetResponseStream()).ReadToEnd()),
        ex => MessageBox.Show(ex.Message));




                                                    例外は最後に統一的処理が可能
  階層構造はフラット
// Taskもそうですが、ラップ用メソッドは事前に拡張メソッドを作っておくと良いです
 public static class WebRequestExtensions
 {
     public static IObservable<WebResponse> GetResponseAsObservable(this WebRequest request)
     {
         return Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetRespo
     }

     public static IObservable<string> DownloadStringAsObservable(this WebRequest request)
     {
         return request.GetResponseAsObservable()
             .Select(res =>
             {
                 using (var sr = new StreamReader(res.GetResponseStream()))
                 {
                     return sr.ReadToEnd();
                 }
             });
                                                           非同期処理とは思えないほど超
     }
 }
                                                            絶的に本体がシンプルになる
事前にラップ用拡張メソッドを用意すると

                         WebRequest.Create("http://localhost:8403/TestAPI.ashx")
                             .DownloadStringAsObservable()
                             .SelectMany(x => WebRequest.Create(x).DownloadStringAsObservable())
                             .ObserveOnDispatcher()
                             .Subscribe(
                                 x => MessageBox.Show(x),
                                 ex => MessageBox.Show(ex.Message));
Future
C# 5.0
 Visual   Studio 11
     http://www.microsoft.com/visualstudio/11/ja-jp
 async/await構文でContinueWithが言語サポート
 それに加えて標準クラスライブラリにもラップ済
  みor専用処理のXxxAsync/XxxTaskAsyncメソッドが
  大量追加
     ライブラリはWinRT/.NET 4.5のみでSL5やWP7には現
      在はなし
     async/await自体は可能なので、自分でラップを作っ
      て拡張メソッドとして用意すればいい
asyncキーワードを足す


private async void Button_Click_1(object sender, RoutedEventArgs e)
{
    try
    {
        var nextUrl = await new WebClient().DownloadStringTaskAsync("http://localhost:8403/TestAPI.as
        var result = await new WebClient().DownloadStringTaskAsync(nextUrl);
        MessageBox.Show(result);
    }
    catch (Exception ex)
    {                                     awaitキーワードで継続
        MessageBox.Show(ex.Message);
    }
}

                           同期構文と何も変わらない例外処理
Rx is awaitable
      Task
         vs RxだったらRxのほうが使いやすい
      ただしC# 5.0ではTaskが圧倒的に使いやすい
      じゃあ将来を見据えてTaskで作ったほうが……?


      Rx(IObservable<T>)もawaitさせることはできます
            現在は実験版リリース or ver.2 Betaのみ対応



var nextUrl = await WebRequest.Create("http://localhost:8403/TestAPI.ashx").DownloadStringAsObservabl
var result await WebRequest.Create(nextUrl).DownloadStringAsObservable()
Task is Observable
 TaskのメソッドはToObservableでRxに変換可能
 SelectManyなど一部の主要なRxの合成系メソッド
   はTaskを直接渡すことに対応
      まだ実験版, Rx v2 Betaのみ


new WebClient().DownloadStringTaskAsync("url").ToObservable()
    .SelectMany(x => new WebClient().DownloadStringTaskAsync(x))
    .Subscribe()
FromAsyncPattern
 Rxはawait可能であること、C#     5.0でTaskベースの
  非同期処理がライブラリレベルでも主流になるこ
  とから、Rx v2ではObservable.FromAsyncPatternは
  Obsolete(非推奨)となりました
 Task.FromAsyncを使い、必要ならばToObservable
  していく
どれを選択すべきか
 Silverlight   4ならばRx一択
     Taskないですから
     将来VS11/SL5に移行してTask中心になったとしても、
      そのままawait出来るので問題はない
 Silverlight
          5ではVS11を見据えて基本的なラップは
  TaskのFromAsyncで行う
     処理自体はContinueWithで組んでもいいけれど、素
      のTaskは使いづらいのでRxを使うのがベター
     同じく将来的にはRxはawait可能なので大丈夫
 WinRTや.NET     4.5 WPFではasync/awaitで
     一つの値を返すものはTask+async/awaitがベスト
非同期ストリーム処理
 Reactive   Extensions
     単体の非同期処理はTaskに譲っても、Rxにはイベン
      ト処理+それらから流れてくるストリームをそのま
      ま非同期処理して、非同期ストリーム化させる、な
      どなど、非同期においても、まだ多くの役割がある


 TPL   Dataflow
     .NET 4.5搭載のTaskベースの非同期ストリーム処理ラ
      イブラリ
     Rxと直接対決になるかどうかはまだ分からない
Rx v2 Beta
 ダウンロードセンター               or NuGetのpre releaseから
 入手可能
     http://www.microsoft.com/download/en/details.aspx?i
      d=29058
 .NET 4.5/SL5/WP 7.1専用
 高速化
 .NET Portable Library対応
     一つのプロジェクトで全てのプラットフォームに対
      応可能になる
まとめ
 C#5.0超素晴らしい
 Rxの立ち位置は、非同期処理では若干難しくなっ
  てきている
    将来的にはシンプルなケースでは完全不要でしょう
    ではRxに価値はないかというとそんなことはなくて、
     メインであるイベント処理への活用や非同期スト
     リーム処理などの方向で使えます
    なにより、現時点での唯一の解

C#次世代非同期処理概観 - Task vs Reactive Extensions

  • 1.
    C#次世代非同期処理概観 Task vs ReactiveExtensions 2012/3/10 #riaarch Yoshifumi Kawai @neuecc
  • 2.
    Profile  Name => Yoshifumi Kawai  仕事は近頃はASP.NETで、あまりRIAじゃなかったり  まあ、HTML5もRIAですし!  Twitter => @neuecc  HN => neuecc  読むときは“のいえ”と読ませてます  サイトのドメイン(特に意味はない)を繋いだだけ で、識別子になればそれだけでいいと思って発音考 えてなかったので割とアレ  Microsoft MVP for Visual C#(2011/4-)
  • 3.
  • 4.
  • 5.
  • 6.
    Agenda  非同期処理とは何か  非同期処理の苦痛 .NET Frameworkにおける非同期処理パターン  C# 5.0(Visual Studio 11)の非同期処理(async/await)  Task vs Rx
  • 7.
  • 8.
    非同期って?  Parallel?  並列 - 一つの処理をバラして同時実行して高速化  Parallel.For/Parallel.ForEach/Parallel LINQ  Concurrent?  並行 - 個別な処理が相互作用したりしなかったり  Thread, Task  Asynchronous!  非同期 - ブロックしない処理  UIスレッドを止めなかったりIO処理効率化だったり  DownloadStringAsyncなどやBeginXxx-EndXxxなど  ThreadやTaskを使っても勿論いい
  • 9.
    非同期はなぜ重要か  「クラウド」並のバズワード、とか言ってみたり  RIA的にはUIスレッドのブロックいくない  ユーザーエクスペリエンス的には当然だろ常考  Silverlight, Windows Phone, Windows 8(WinRT)には最 初から非同期メソッドしか用意されていない(同期 処理不可!)  JavaScriptなんて最初からそれOnlyですしね  Web的には同時接続対策  C10K問題  http://www.hyuki.com/yukiwiki/wiki.cgi?TheC10kProblem  node.jsの流行にC#erとしてはC# 5.0で対抗する!
  • 10.
  • 11.
  • 12.
    ネスト宇宙ヤバイ  単発ならそれほどでもない  ネストすると人類の手に負えない varwc = new WebClient(); wc.DownloadStringCompleted += (_, res) => { var wc2 = new WebClient(); wc2.DownloadStringCompleted += (__, res2) => { MessageBox.Show(res2.Result); }; wc2.DownloadStringAsync(new Uri(res.Result)); }; wc.DownloadStringAsync(new Uri("http://localhost:8403/TestAPI.ashx"));
  • 13.
    例外処理不能  というかもう無理。 var wc= new WebClient(); wc.DownloadStringCompleted += (_, res) => { if (res.Error != null) { MessageBox.Show(res.Error.Message); } var wc2 = new WebClient(); wc2.DownloadStringCompleted += (__, res2) => { if (res2.Error != null) { MessageBox.Show(res2.Error.Message); } MessageBox.Show(res2.Result); }; wc2.DownloadStringAsync(new Uri(res.Result)); }; wc.DownloadStringAsync(new Uri("http://localhost:8403/TestAPI.ashx"));
  • 14.
  • 15.
    APMとは  Asynchronous ProgrammingModel  BeginXxx-EndXxxのペアによる非同期処理  WebRequest#BeginGetResponse-EndGetResponse のようなもの  とにかく面倒くさい  ラムダ式登場で割と緩和されたけれど  正しく使うのは慣れが必要  後述するTaskやRxのベースとして活躍  .NETにおけるもっともプリミティブな非同期シス テムと考えていただければ
  • 16.
    var req =WebRequest.Create("http://localhost:8403/TestAPI.ashx"); req.BeginGetResponse(ar => 非同期処理中の例外はEndのタイミングで伝送 { try { var res = req.EndGetResponse(ar); var req2 = WebRequest.Create(new StreamReader(res.GetResponseStream()).ReadToEnd()); req2.BeginGetResponse(ar2 => { UIスレッドへ通達する必要がある try { var res2 = req2.EndGetResponse(ar2); var result = new StreamReader(res2.GetResponseStream()).ReadToEnd(); Dispatcher.BeginInvoke(() => MessageBox.Show(result)); } catch (Exception ex2) { Dispatcher.BeginIncoke(()=> MessageBox.Show("inner error " + ex2.Message)); } }, null); } catch (Exception ex1) catchできるのは同じ関数のブロック内だけ { Dispatcher.BeginIncoke(()=> MessageBox.Show("outer error " + ex1.Message)); } }, null);
  • 17.
    EAPとは  Event-BasedAsynchronous Pattern XxxAsyncメソッド + XxxCompletedイベントのペア による非同期処理  WebClient#DownloadStringAsyncのようなもの  素の状態のC#では割と楽な書き方  リクエストの発行が後になるという順序の問題を 抱える  後述するTaskやRxの登場でサヨウナラ行き  TaskやRxでラップするのも面倒くさいという
  • 18.
    UIスレッドまわりは自動で面倒 var wc =new WebClient(); wc.DownloadStringCompleted += (_, res) => みてくれる(WebClientの場合) { if (res.Error != null) { MessageBox.Show(res.Error.Message); } var wc2 = new WebClient(); wc2.DownloadStringCompleted += (__, res2) => { if (res2.Error != null) { 先にイベントを登録して MessageBox.Show(res2.Error.Message); } MessageBox.Show(res2.Result); }; wc2.DownloadStringAsync(new Uri(res.Result)); }; wc.DownloadStringAsync(new Uri("http://localhost:8403/TestAPI.ashx")); リクエストの発行は後で行う(順序が逆だとダメ!)
  • 19.
    TAPとは  TaskBased AsynchronousPattern  .NET 4/SL5以降登場したTPLを使った非同期処理  TPLはTask Parallel Libraryの略  Threadを概ね置き換えます  Task.Factory.FromAsyncでAPMをラップ  .NET 4.5やWinRTにはフレームワークに最初から ラップ済み or TAP用に書かれた専用メソッドが大 量追加  WebRequest#GetResponseAsyncとか  WebClient#DownloadStringAsyncとか
  • 20.
    UIスレッド用スケジューラを用意することで 個別BeginInvoke不要 var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); APMをラップする var req = WebRequest.Create("http://localhost:8403/TestAPI.ashx"); Task.Factory.FromAsync<WebResponse>(req.BeginGetResponse, req.EndGetResponse, null) .ContinueWith(res => { var req2 = WebRequest.Create(new StreamReader(res.Result.GetResponseStream()).ReadToEnd()); return Task.Factory.FromAsync<WebResponse>(req2.BeginGetResponse, req2.EndGetResponse, null); }) .Unwrap() .ContinueWith(res => ネストしたTaskは明示的にUnwrap { MessageBox.Show(new StreamReader(res.Result.GetResponseStream()).ReadToEnd()); }, uiScheduler) .ContinueWith(res => { MessageBox.Show(res.Exception.Message); }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, uiScheduler); 階層構造はフラット 例外は最後に統一的処理が可能
  • 21.
    Rxとは  Reactive Extensions  http://msdn.microsoft.com/en-us/devlabs/gg577609  LINQベースのイベント・非同期処理ライブラリ  LINQ to Events, LINQ to Asynchronous  WP7には同梱、JavaScript版もあり  @ITで連載やってるので読んでね!  http://www.atmarkit.co.jp/fdotnet/introrx/index/index. html  LINQベースのため合成処理が異常なほど強力  非同期処理だけではなくあらゆる用途に使える
  • 22.
    APMをラップする var req =WebRequest.Create("http://localhost:8403/TestAPI.ashx"); Observable.FromAsyncPattern<WebResponse>(req.BeginGetResponse, req.EndGetResponse)() .SelectMany(res => { var next = new StreamReader(res.GetResponseStream()).ReadToEnd(); var req2 = WebRequest.Create(next); return Observable.FromAsyncPattern<WebResponse>(req2.BeginGetResponse, req2.EndGetResponse)() }) .ObserveOnDispatcher() 実行スレッドのコントロール .Subscribe( res => MessageBox.Show(new StreamReader(res.GetResponseStream()).ReadToEnd()), ex => MessageBox.Show(ex.Message)); 例外は最後に統一的処理が可能 階層構造はフラット
  • 23.
    // Taskもそうですが、ラップ用メソッドは事前に拡張メソッドを作っておくと良いです publicstatic class WebRequestExtensions { public static IObservable<WebResponse> GetResponseAsObservable(this WebRequest request) { return Observable.FromAsyncPattern<WebResponse>(request.BeginGetResponse, request.EndGetRespo } public static IObservable<string> DownloadStringAsObservable(this WebRequest request) { return request.GetResponseAsObservable() .Select(res => { using (var sr = new StreamReader(res.GetResponseStream())) { return sr.ReadToEnd(); } }); 非同期処理とは思えないほど超 } } 絶的に本体がシンプルになる 事前にラップ用拡張メソッドを用意すると WebRequest.Create("http://localhost:8403/TestAPI.ashx") .DownloadStringAsObservable() .SelectMany(x => WebRequest.Create(x).DownloadStringAsObservable()) .ObserveOnDispatcher() .Subscribe( x => MessageBox.Show(x), ex => MessageBox.Show(ex.Message));
  • 24.
  • 25.
    C# 5.0  Visual Studio 11  http://www.microsoft.com/visualstudio/11/ja-jp  async/await構文でContinueWithが言語サポート  それに加えて標準クラスライブラリにもラップ済 みor専用処理のXxxAsync/XxxTaskAsyncメソッドが 大量追加  ライブラリはWinRT/.NET 4.5のみでSL5やWP7には現 在はなし  async/await自体は可能なので、自分でラップを作っ て拡張メソッドとして用意すればいい
  • 26.
    asyncキーワードを足す private async voidButton_Click_1(object sender, RoutedEventArgs e) { try { var nextUrl = await new WebClient().DownloadStringTaskAsync("http://localhost:8403/TestAPI.as var result = await new WebClient().DownloadStringTaskAsync(nextUrl); MessageBox.Show(result); } catch (Exception ex) { awaitキーワードで継続 MessageBox.Show(ex.Message); } } 同期構文と何も変わらない例外処理
  • 27.
    Rx is awaitable  Task vs RxだったらRxのほうが使いやすい  ただしC# 5.0ではTaskが圧倒的に使いやすい  じゃあ将来を見据えてTaskで作ったほうが……?  Rx(IObservable<T>)もawaitさせることはできます  現在は実験版リリース or ver.2 Betaのみ対応 var nextUrl = await WebRequest.Create("http://localhost:8403/TestAPI.ashx").DownloadStringAsObservabl var result await WebRequest.Create(nextUrl).DownloadStringAsObservable()
  • 28.
    Task is Observable TaskのメソッドはToObservableでRxに変換可能  SelectManyなど一部の主要なRxの合成系メソッド はTaskを直接渡すことに対応  まだ実験版, Rx v2 Betaのみ new WebClient().DownloadStringTaskAsync("url").ToObservable() .SelectMany(x => new WebClient().DownloadStringTaskAsync(x)) .Subscribe()
  • 29.
    FromAsyncPattern  Rxはawait可能であること、C# 5.0でTaskベースの 非同期処理がライブラリレベルでも主流になるこ とから、Rx v2ではObservable.FromAsyncPatternは Obsolete(非推奨)となりました  Task.FromAsyncを使い、必要ならばToObservable していく
  • 30.
    どれを選択すべきか  Silverlight 4ならばRx一択  Taskないですから  将来VS11/SL5に移行してTask中心になったとしても、 そのままawait出来るので問題はない  Silverlight 5ではVS11を見据えて基本的なラップは TaskのFromAsyncで行う  処理自体はContinueWithで組んでもいいけれど、素 のTaskは使いづらいのでRxを使うのがベター  同じく将来的にはRxはawait可能なので大丈夫  WinRTや.NET 4.5 WPFではasync/awaitで  一つの値を返すものはTask+async/awaitがベスト
  • 31.
    非同期ストリーム処理  Reactive Extensions  単体の非同期処理はTaskに譲っても、Rxにはイベン ト処理+それらから流れてくるストリームをそのま ま非同期処理して、非同期ストリーム化させる、な どなど、非同期においても、まだ多くの役割がある  TPL Dataflow  .NET 4.5搭載のTaskベースの非同期ストリーム処理ラ イブラリ  Rxと直接対決になるかどうかはまだ分からない
  • 32.
    Rx v2 Beta ダウンロードセンター or NuGetのpre releaseから 入手可能  http://www.microsoft.com/download/en/details.aspx?i d=29058  .NET 4.5/SL5/WP 7.1専用  高速化  .NET Portable Library対応  一つのプロジェクトで全てのプラットフォームに対 応可能になる
  • 33.
    まとめ  C#5.0超素晴らしい  Rxの立ち位置は、非同期処理では若干難しくなっ てきている  将来的にはシンプルなケースでは完全不要でしょう  ではRxに価値はないかというとそんなことはなくて、 メインであるイベント処理への活用や非同期スト リーム処理などの方向で使えます  なにより、現時点での唯一の解