かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

Reactive Extensions入門 5「イベントを監視する」

前回は、Observableクラスに定義されたメソッドをいくつか紹介しました。今回は、いよいよ実際に使いでのあるメソッドを紹介しようと思います。

今まで紹介したメソッドは、どちらかというと動作確認に使うのに適してると思います・・・。

さて、Reactive Extensionsは乱暴にいうとObserverパターンです。そして、.NETではObserverパターンはイベントで実現されています。ということはイベントをReactive ExtensionsのIObservableにすることも出来るはずです。そのような仕事をしてくれるのが、Observable.FromEventというメソッドです。

色々なオーバーライドがあるのですが、一番楽なのは文字列でイベント名を指定する方法です。早速見てみましょう。

// イベントのデリゲートとイベント引数
delegate void SampleEventHandler(object sender, SampleEventArgs e);
class SampleEventArgs : EventArgs
{
    public string Value { get; private set; }
    public SampleEventArgs (string value)
	{
        this.Value = value;
	}
}
// イベントを発行するだけのオブジェクト
class EventSource
{
    public event SampleEventHandler SampleEvent;
    public void OnSampleEvent(string value)
    {
        if (this.SampleEvent != null)
        {
            this.SampleEvent(this, new SampleEventArgs(value));
        }
    }
}

上記のクラスのSampleEventを監視して、イベントが発行されたらコンソールに値を出す処理をReactive Extensionsでやってみます。

var source = new EventSource();

// sourceのSampleEventを監視する
Observable.FromEvent<SampleEventArgs>(source, "SampleEvent")
    .Subscribe(e =>
        {
            // 適当に値出力
            Console.WriteLine("Raise Event");
            Console.WriteLine("  sender : " + e.Sender);
            Console.WriteLine("  value : " + e.EventArgs.Value);
        });

// イベントを発行する
source.OnSampleEvent("Hello");
source.OnSampleEvent("World");

実行結果は以下のようになります。

Raise Event
  sender : ConsoleApplication16.EventSource
  value : Hello
Raise Event
  sender : ConsoleApplication16.EventSource
  value : World

こんな感じです。因みにFromEventには以下のような書き方のバリエーションもあります。

Observable.FromEvent(
    (EventHandler<SampleEventArgs> h) => new SampleEventHandler(h),
    h => source.SampleEvent += h,
    h => source.SampleEvent -= h)

性能的には文字列指定じゃないほうがいいと思いますが・・・好みの問題だと思います。