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));
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()