Skip to content

FromEventHandler

1. 概要

FromEventHandler は、.NET 標準の EventHandler / EventHandler<TEventArgs> パターンのイベントを Observable に変換するための簡便メソッドです。

戻り値はタプル (object? sender, EventArgs e) または (object? sender, TEventArgs e) で、送信元オブジェクトとイベント引数の両方にアクセスできます。

通常は、対象のイベントが EventHandler / EventHandler<TEventArgs> 型ならこちらを使います。Action / Action<T> ベースのイベントや独自デリゲート型のイベントでは FromEvent を使います。

2. シグネチャ

EventHandler(非ジェネリック)

csharp
public static Observable<(object? sender, EventArgs e)> FromEventHandler(Action<EventHandler> addHandler, Action<EventHandler> removeHandler, CancellationToken cancellationToken = default)

標準の EventHandler 型イベントを変換します。senderEventArgs のタプルを発行します。

csharp
Observable.FromEventHandler(
    h => source.Changed += h,
    h => source.Changed -= h)

EventHandler<TEventArgs>(ジェネリック)

csharp
public static Observable<(object? sender, TEventArgs e)> FromEventHandler<TEventArgs>(Action<EventHandler<TEventArgs>> addHandler, Action<EventHandler<TEventArgs>> removeHandler, CancellationToken cancellationToken = default)

EventHandler<TEventArgs> 型イベントを変換します。sender と型付きのイベント引数 TEventArgs のタプルを発行します。

csharp
Observable.FromEventHandler<PropertyChangedEventArgs>(
    h => source.PropertyChanged += h,
    h => source.PropertyChanged -= h)

3. マーブルダイアグラム

FromEventHandler のマーブルダイアグラム

イベントが発火するたびに (sender, e) タプルが発行されます。CancellationToken がキャンセルされるとイベントハンドラが解除され、シーケンスが完了します。

4. サンプルコード

csharp
using R3;
using System.ComponentModel;

// === 非ジェネリック EventHandler ===
var fileWatcher = new FileSystemWatcher(".");

Observable.FromEventHandler(
        h => fileWatcher.Changed += h,
        h => fileWatcher.Changed -= h)
    .Subscribe(x => Console.WriteLine($"変更検知: sender={x.sender}, args={x.e}"));

// === ジェネリック EventHandler<TEventArgs> ===
var process = new Process();

Observable.FromEventHandler<DataReceivedEventArgs>(
        h => process.OutputDataReceived += h,
        h => process.OutputDataReceived -= h)
    .Subscribe(x => Console.WriteLine($"出力: {x.e.Data}"));
// 出力例: 出力: Hello World

// === sender は不要でイベント引数だけ使いたい場合 ===
Observable.FromEventHandler<DataReceivedEventArgs>(
        h => process.OutputDataReceived += h,
        h => process.OutputDataReceived -= h)
    .Select(x => x.e.Data)
    .Where(data => data is not null)
    .Subscribe(data => Console.WriteLine(data));

5. 補足

FromEvent との違い

FromEvent はすべてのデリゲート型に対応する汎用メソッドです。EventHandler / EventHandler<TEventArgs> 以外のデリゲート型(例: Action<T> やカスタムデリゲート)を使うイベントの場合は FromEvent を使用してください。

FromEventHandlerEventHandler パターン専用であり、デリゲート変換関数を指定する必要がないため、より簡潔に記述できます。