Reactive Extensions RC0リリースによる変更点

DevLabsの実験的プロジェクトからData Developer Centerへの正式プロジェクトとして昇格したRxですが、ついにDevLabsのページ自体が消滅(リダイレクトされる)し、いよいよ実験的なノリは一段落し、正式なプロジェクトとしての道を歩み始めたようです。その手始めとして、馬鹿デカい破壊的変更がやってきました。……っていきなりなんじゃそりゃ。

今回の変更はRC0、そしてStableであると銘打たれ、(今度こそ)APIの破壊的変更はないものと思われます。きっとAPIを変更するなら本当の本当に最後のタイミングだから、ということなのでしょうね、変更の嵐は。そんなわけで、DLLの分け方が変わってるし、名前空間も全部変わってるし、メソッド名もばかばか変わってるし、メソッドシグネチャも変わってるし、なくなったのもあるし、大量すぎて書ききれないほどに変更点がある。

しかし、本当の本当に安定版の始まりなので、つまり、学ぶなら今からが正に最適ということです!また、基本的な使い方が変わったわけではないので、既存の知識は生かせますしコード自体もそのままでも大体は行けます。大体は。

詳しい変更内容自体はフォーラム New Release: Reactive Extensions v1.0.10425 に書かれています。こういうのはフォーラムじゃなくてBlogのほうでちゃんと告知してください……。リリースから半月近く経つのに、まだBlogのほうは更新されてないという。

Rxの入手方法・パッケージ・DLL内容について Part2

以前にReactive Extensionsを学習するためのリソースまとめとしてまとめましたが、そのうちDLL内容がまるっと変わったので、そこの部分を修正します。なお、学習リソースについては変りないので、以前のまとめ記事をそのまま参照してください。また、Windows Phone 7に標準搭載されているものは(当然)変わりはありません。最近WP7本体のアップデートにコソッと紛れて更新(バグフィックス)されたようですけど。

Reactive ExtensionsのGet itからDownloadするといいでしょう。色々書いてありますが、2のDownload the Reactive ExtensionsからRx for all Platformsを選べばよいかと思います。

StableとExperimentalがあるように、安定版と実験版に分かれています。そして現時点ではそのページのExperimentalをクリックしてもExperimentalは手に入りません(なにそれ……)。Experimentalが欲しい人はMicrosoft Download Center: Search ResultsのExperimental Releaseから入手するといいでしょう。バージョン番号は、Stableは1.0.10425、Experimentalは1.1.10425になっています。

けれど、何だかんだで更新頻度が高いので、NuGet経由での利用が一番お薦めです。

が、NuGetの画面は新旧入り乱れていて何を入れていいか分からないカオスになっていたりして。説明すると、Rx-Mainとか、名前がRx-になっているものが新しいもので選ぶべきもの。Reactive Extensions -のものは古い残骸なので無視してください。また、NuGet経由で入るものはExperimentalのほうになります。

さて、今回からDLL類の分類がばっさり変わりました。

  • System.Reactive (NuGetではRx-Main)

以前あったCoreExは消滅し、コアコンポーネントはSystem.Reactiveのみとなりました。また、名前空間も全てSystem.Reactive以下に集められていて、例えば今までObservableクラスはSystem.Linqでしたが、今回よりSystem.Reactive.Linqに変更されました(拡張メソッドの利用に名前空間の参照は必須なので、この名前空間のusingは忘れずに)。

  • System.Reactive.Windows.Threading (NuGetではRx-WPF/Rx-Silverlight)

WPF/Silverlight向けでDispatcherに対するObserveOnとSubscribeOnのオーバーロードが追加されています。また、Dispatcher.CurrentDispatcherに対してObserveOn/SubscribeOnを行うObserveOnDispatcher/SubscribeOnDispatcherの利用もこのDLLの参照が必要になりました。それとDispatcherに対してBeginInvokeして実行するスケジューラDispatcherSchedulerが追加されました。

WPF/SilverlightでRxを使う場合はこれの参照は必需と思われます。NuGetを使う場合は依存の解決で、これを選択するとRx-Mainも入れてくれるので、こちらからInstallすると良いでしょう。

  • System.Reactive.Windows.Forms (NuGetではRx-WinForms)

WindowsFormsのControlに対するObserveOnとSubscribeOnのオーバーロードが追加されています。それとControlScheduler(Controlに対してBeginInvokeして実行するスケジューラ)。それだけです。というわけで、その名の通りWinFormsで使う場合だけ、あると便利。

  • System.Reactive.Providers (NuGetではRx-Providers)

Qbservableが収納されています。QbservableはIEnumerableに対するIQueryableみたいなもので、式木からObservableを生成するためのもの。今のとこ有効活用されている例も人もいないと思われます。(というかよく正式リリースにも生き残ったものだ、ぐらいの)。ちなみにQueryable Observableの略だそうで。QBみたいなものだと思えば可愛い!

例えばLinq to Twitterを非同期しかないSilverlightでやるなら、これを使うのが適切でしょう。現状だとコールバックでどうだのという格好悪い仕組みなので。(但し、System.Reactive.Providersは現状ではDesktop版にしか同梱されていませんが)。あとは公式の例として挙げられているWQL Provider。WMIに対するSQLで、クエリ結果はイベント(つまりRx)になる。非常に都合よくQbservableに当てはまるようになってますね。なってるんですが、そう都合よく当てはまるのはこれぐらいしかないのではないか、感もあったり。

いや、むしろ全て非同期なら全部Rxでいいんですよぅー、to SqlだってSqlCommandのBeginExecuteReaderでやればIQueryableじゃなくてIQbservableの出番なんですよぅー。……とはいっても、誰がやるかって話ですね。

  • Microsoft.Reactive.Testing.dll (NuGetではRx-Testing)

ユニットテスト用のモック生成クラス群。使いやすさ的には個人的にはちょっと微妙で、今一つ上手く活用出来なくて色々見送り中。

FromEvent/FromEventPattern

BufferWithCount/BufferWithTimeが統合されてメソッド名がBufferになった、程度の変更は割とどうでもいいのですが、Rxの中核であるFromEventに大きな変更があったのは見逃せません。簡単に解説します。

今までFromEventというメソッド名だったものはFromEventPatternに変わりました。また、戻り値がIEventからEventPatternというものになりましたが、中身はプロパティにSenderとEventArgsを持つという、ほとんど同じものなので、感覚的には一緒です。今までの私の記事や古いウェブ上の記事を見る際にFromEventが使われていたら、それはFromEventPatternに置き換えてください。そうすれば、そのままで動きます。

では新しく新設されたことになるFromEventは何なのかというと、よくわかりません:) そのうち使い方の説明とか出てくると思うのでそれ待ちで……。いやすみません。

ところでInteractiveはどうしたの?ClientProfileは?Asyncは?

死にました。というのもアレですが、とりあえず先行きは不透明です。少なくともStableに同梱されることはないそうです。Experimental側でのリリースは、一応計画はされているようですが、現状は同梱されていません。どうなるんでしょうかねえ……。Interactiveは欲しい人はNuGetに古いのが残っているので、それを使えば、ですね……。

Experimental

さて、今のところ、どのメソッドが実験的とされているのか、見てみましょう。幸いExperimentalAttributeでマークされているので、確認はコードで容易に出来ます。

typeof(System.Reactive.Linq.Observable)
    .GetMethods()
    .Where(mi => mi.GetCustomAttributes(typeof(ExperimentalAttribute), false).Any())
    .Select(mi => mi.Name)
    .Distinct()
    .OrderBy(s => s)
    .ToList() // Interactiveが消滅してしまったから...
    .ForEach(Console.WriteLine);

// 実行結果
Case
Create // 追加のオーバーロードのみ、通常のはExperimentalではない
DoWhile
Expand
For
ForEachAsync
ForkJoin
GetAwaiter
If
IsEmpty
Let
ManySelect
Remotable
Start // 追加のオーバーロードのみ、通常のはExperimentalではない
While

あまり大したものは入ってないようなので、そんな気にすることもないですね。Expandは是非入れてきて欲しいところなのだけど。CreateやStartのオーバーロードはかなりややこしい事になっているので、実験的扱いなのは納得。

ReactiveOAuth ver.0.3.0.0

そんな大移動があったわけでReactiveOAuthも動かなくなってしまった。というわけで更新しました(WP7版の人は気にしなくてもいいです)。

機能は変わってなし。とりあえず最新版のRxで動くように、というだけです。コードが、とにかく名前空間が変わったので全部書き換えて、かなり面倒……。そして一部のメソッドは名前が変わったので、WP7版と完全にコードを共有していたので発狂。ifディレクティブでメソッド呼び出し部分をひたすら書き換え、などというのは見通しも悪いし格好悪いしで最悪なので、別の方法として、WP7側に拡張メソッド作ってコード上の互換を維持するようにしました。

public static class ObservableForCompatible
{
    // 本体のコードはRx RC0に合わせて、WP7側だけ拡張メソッドで同名のものを作って対処
    public static IObservable<IList<T>> Buffer<T>(this IObservable<T> source, int count)
    {
        return source.BufferWithCount(count);
    }
}

他にも挙動が若干変わってるのがあって原因掴むのに泣きそうになったりとか、思った以上に大変だった……。Stableと銘打ってるのに、次にこのクラスの大変更があったらさすがにブチ切れます。今回は、まあ、許す。

Reactive Extensions Extensions(Rxx)

コミュニティから面白いライブラリも上がってきています。

Rx拡張メソッド集。C# 3.0の時も俺々拡張メソッドライブラリがいっぱい出てきましたが、そのノリですね。でも実際、Rx自体は原始的な機能のみなので、非同期処理とかイベント処理にフォーカスする場合は、もう一つ上の層で軽くラップしたライブラリは間違いなく必要だなと思っていますので、こういうのはいいな、と。私自身も非同期処理はReactive Extensions用のWebRequest拡張メソッドとして、結構ガッツし仕込んだものを使い回していて(ReactiveOAuthやUtakotoha の内部はこれ)かなり重宝しています。余裕が出たら、このRxxプロジェクトにJoinしたいな、と思ってます。

Rxの本

オライリーから出ているProgramming C#でお馴染みのJesse Libertyと、共著者としてReactiveUIというRxでWPFのGUI面をサポートするライブラリを作成しているPaul Betts(Microsoft Office Labsに所属)による、Rxの本が今年の秋頃に出る予定です。

執筆陣が豪華だしページ数も現時点amazon表示で300ページと、立派な仕上がりを予感させます。私は予約したよ!

まとめ

今回こそStableなはずなので、ようやーく人に自信を持って薦められるようになりました!いやマヂで。API的にも多分、じゃなくて絶対安定したわけなので、飛び込むなら今!です。

ところで本題とは関係ないんですがスマートフォン勉強会 - すまべん特別編「Windows Phone 7 開発ブーストアップ」@関東でWP7+Rxのセッションをします。入門編として、主に非同期処理にフォーカスして、今すぐコピペで使ってコールバックを撲殺しよう、といった内容を考えていますので、是非聞きに来てください。

Profile

Yoshifumi Kawai

Cysharp, Inc
CEO/CTO

Microsoft MVP for Developer Technologies(C#)
April 2011
|
July 2024

Twitter:@neuecc GitHub:neuecc

Archive