既存の .NET イベントを使用したブリッジ

Rx には、Rx によって提供される豊富な構成、フィルター処理、およびリソース管理機能をあらゆる種類のデータ ストリームに使用できるように、.NET の既存の非同期ソースとブリッジするためのファクトリ メソッドが用意されています。 このトピックでは、観察可能なシーケンスとして Rx に .NET イベントを "インポート" できるようにする FromEventPattern 演算子について説明します。 イベントが発生するたびに、OnNext メッセージが監視可能なシーケンスに配信されます。 その後、他の監視可能なシーケンスと同様に、イベント データを操作できます。

Rx は、.NET イベント、非同期パターン、タスク並列ライブラリなどの既存の非同期プログラミング モデルを置き換えることを目的としていません。 ただし、イベントを作成しようとすると、Rx のファクトリ メソッドによって、現在のプログラミング モデルでは見つからない便利な機能が提供されます。 これは、リソースのメンテナンス (サブスクリプションを解除するタイミングなど) とフィルター処理 (受信するデータの種類の選択など) に特に当てはまります。 このトピックと後続の Rx 機能では、これらの Rx 機能が非同期プログラミングにどのように役立つかを確認できます。

.NET イベントを Rx Observable シーケンスに変換する

次の例では、マウス移動イベントの単純な .NET イベント ハンドラーを作成し、Windows フォームのラベルにマウスの位置を出力します。

using System.Linq;
using System.Windows.Forms;
using System.Reactive;
using System.Reactive.Linq;
using System;
using WinForm;
using System.Reactive.Disposables;

class Program {
 
    static void Main() 
    {
         var lbl = new Label(); 
         var frm = new Form { Controls = { lbl } }; 
         frm.MouseMove += (sender, args) =>
         {
              lbl.Text = args.Location.ToString();
         };
         Application.Run(frm);
    }; 
}

Rx にイベントをインポートするには、FromEventPattern 演算子を使用し、ブリッジされるイベントによって発生する EventArgs オブジェクトを指定します。 FromEventPattern 演算子は、オブジェクトの送信者と一部の EventArgs を受け取るイベントを処理し、リフレクションを使用してそれらの add/remove メソッドを検索します。 次に、指定されたイベントを、送信者とイベント引数の両方をキャプチャする EventPattern 型を持つ監視可能なシーケンスに変換します。

1 つのパラメーター (非標準イベント) を持つデリゲートの場合は、ハンドラーのアタッチとデタッチに使用される関数のペアを受け取る FromEvent 演算子を使用できます。

次の例では、Windows フォームのマウス移動イベント ストリームを監視可能なシーケンスに変換します。 マウス移動イベントが発生するたびに、サブスクライバーは OnNext 通知を受け取ります。 その後、このような通知の EventArgs 値を調べて、マウス移動の場所を取得できます。

using System.Linq;
using System.Windows.Forms;
using System.Reactive;
using System.Reactive.Linq;
using System;
using WinForm;
using System.Reactive.Disposables;

class Program {
 
    static void Main() 
    {
         var lbl = new Label(); 
         var frm = new Form { Controls = { lbl } }; 
         IObservable<EventPattern<MouseEventArgs>> move = Observable.FromEventPattern<MouseEventArgs>(frm, "MouseMove");
         move.Subscribe(evt => { 
                             lbl.Text = evt.EventArgs.Location.ToString(); 
                       }) ;
         Application.Run(frm);
   }; 
}

このサンプルでは、 move が、さらに操作できる監視可能なシーケンスになることに注意してください。 「 LINQ 演算子を使用した監視可能なシーケンスのクエリ 」トピックでは、このシーケンスを Points 型のコレクションに投影し、そのコンテンツをフィルター処理する方法について説明します。これにより、アプリケーションは特定の条件を満たす値のみを受け取ります。

イベント ハンドラーのクリーンアップは、Subscribe メソッドによって返される IDisposable オブジェクトによって処理されます。 Dispose を呼び出すと (この例では using ブロックの末尾に達します)、基になるイベント ハンドラーを含むシーケンスで使用されているすべてのリソースが解放されます。 これは基本的に、ユーザーに代わってイベントへの登録を解除する処理を行います。

参照

概念

LINQ 演算子を使用した監視可能シーケンスのクエリ