LoginSignup
0
3

More than 5 years have passed since last update.

.Net System.Reactive の使い方。イベントアグリゲータのサンプル

Last updated at Posted at 2017-11-05

.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使うなら色々できまっせ〜
ファクトリでソースを作ってあげれば良いのですけど、色々ありすぎて逆に使いづらい(暴言!)

以上

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3