.Netで使うRxの覚え書き
Rx,Reactive Extentionとは
さっくり省略。別記事(他の人の)を参照してね。
なんに使えるの?
解釈が人によりそうだけど、イベント処理・タイマーなどかな。
ただし、簡単なイベント処理なら自前で処理する、タイマーならOSサービスやらを使った方が良いですよ。
便利なんだけど、いまいちLinqに比べて普及しない所はやや複雑だからかな〜
.NetのRxは...
使ってるプラットフォームにより、一部記述に違いがあるようだ。
他人のサンプルをそのままコピペしても動かないことがあるよ〜
ついでに、ライブラリの方にも変更があるから、それについて行く必要もあるよ〜
たとえば、ライブラリのNuget参照名がRx-MainからSystem.Reactiveになってたり。
なのでサンプルを自分用に作った
ここでのコードは、Windows Desktop, Form用。
(WinFormsで使うことを考えて作ってみたけど、ここに書いた程度では影響ほとんど無いか。。。)
イベントアグリゲータを作ってみた。
ここのサンプルは、System.Reactive Ver3.1.1でのこと。
イベントアグリゲータってなに?
省略。Wow
どんなメッセージ送れるの?
指定のインタフェースを実装したオブジェクトが送信できる。
メッセージの種類は、このオブジェクトの型で分けている。なので、同じ型でリスナを登録すると、全部にメッセージが送られるぞ。
インタフェース
- アグリゲータ
- イベントリスナの登録 Subscribe
- イベント発行 Publish
- イベントメッセージ
- (空っぽ)必要に応じて付けてくれ〜
public interface IAggregator : IDisposable
{
IDisposable Subscribe<T>(Action<T> action) where T : IEventArgs;
void Publish<T>(T @event) where T : IEventArgs;
}
public interface IEventArgs
{
}
アグリゲータの実装
using System.Reactive.Linq;
using System.Reactive.Subjects;
public class Aggregator : IAggregator
{
public void Dispose()
{
_subject.Dispose();
}
readonly Subject<object> _subject = new Subject<object>();
public void Publish<T>(T @event) where T : IEventArgs
{
_subject.OnNext(@event);
}
public IDisposable Subscribe<T>(Action<T> action) where T : IEventArgs
{
return _subject.OfType<T>()
.AsObservable()
.Subscribe(action);
}
}
イベントメッセージの実装
とりあえずのサンプル。文字列を持つ形で作ってみた。
この部分からは、実際の実装に合わせて変更すべき所ですよ。
public class EventParam : IEventArgs
{
public string Msg { get; set; }
public EventParam(string s)
{
Msg = s;
}
}
使い方サンプル部分
イベントリスナ側
//アグリゲータの実体定義
//これだけはいつも必要
IAggregator agre;
agre = new Aggregator();
//残りはリスナに合わせて実装する
//ここのはまあ、こんな感じで
EventParam receivedEvent = null;
void Handler(EventParam ep) => receivedEvent = ep;
agre.Subscribe((Action<EventParam>)Handler);
//もう一つ
var a = new Action<EventParam>((x) =>
{
System.Diagnostics.Trace.WriteLine("receive;" + x.Msg);
});
var tok = agre.Subscribe(a);
イベント発行側
イベント発行と解除。解除は必要ならするでOK。
//イベント発行
agre.Publish(new EventParam("hello"));
//リスナ削除
tok.Dispose();
〆
イベントアグリゲータとしてはこんな感じでしょうか。
今回イベントソースを手動でやってますけど、Rx使うなら色々できまっせ〜
ファクトリでソースを作ってあげれば良いのですけど、色々ありすぎて逆に使いづらい(暴言!)
以上