Peng Dai
Peng Dai

Reputation: 3

How Rx.Net Observable.FromEventPattern working

I am interested in the Rx.Net. And looking at the [https://learn.microsoft.com/en-us/previous-versions/dotnet/reactive-extensions/hh211731(v=vs.103)][1]

[1]: Observable.FromEventPattern method. The two parameters: addHandler and removeHandler interest me. I thought this two handler won't execute, they are just the dummy parameter, and useless. So when I change the codes as below - Bind different handler to the button click event, the Observable doesn't trigger the Observer any more.

Anyone can explain a bit more about here why never invoked h(RoutedEventHandler) is important?

public MainWindow()
    {
        InitializeComponent();
        IObservable<EventPattern<RoutedEventArgs>> clicks = Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
            h => {
                Console.WriteLine("AddHandler for {the second button}");
                secondButton.Click += AnotherHandler;
            }, 
            h=> secondButton.Click -= AnotherHandler);
        clicks.SubscribConsole("Example");
    }

    private void AnotherHandler(object sender, RoutedEventArgs args)
    {

    }
    private void Button_Click(object sender, RoutedEventArgs e)
    {

        Console.WriteLine("Button click");
    }

Upvotes: 0

Views: 1330

Answers (1)

Magnus
Magnus

Reputation: 363

The removeHandler action is called when you unsubscribe the observable.

It's important, as this is the way you unsubscribe from the event - and it's considered important to unsubscribe from events in order to avoid resource leaks.

In the example below, I have two buttons. One is the 'secondButton' tied to the observable. The other button, unsubscribes the subscription to the observable.

If I click 'secondButton' three times, and then click 'UnsubscribeButton' I get this output in the console:

Added event handler
secondButton clicked
secondButton clicked
secondButton clicked
Unsubscribe button clicked
Removed event handler

So you see, when the FromEvent observable is subscribed to, the addHandler action is invoked. The observable now ticks each time the 'secondButton' is clicked. When the observable is disposed, the removeHandler action is invoked.

If I subsequently try to click 'secondButton' nothing happens - because it's unsubscribed.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Handle secondButton clicks
        IObservable<EventPattern<RoutedEventArgs>> clicks = Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
            h =>
            {
                secondButton.Click += h;
                Console.WriteLine("Added event handler");
            },
            h =>
            {
                secondButton.Click -= h;
                Console.WriteLine("Removed event handler");
            });

        var subscription = clicks.Subscribe(_ => Console.WriteLine("secondButton clicked"));

        // Handle UnsubscribeButton clicks
        Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
                h => UnsubscribeButton.Click += h,
                h => UnsubscribeButton.Click -= h)
            .Subscribe(_ =>
            {
                Console.WriteLine("Unsubscribe button clicked");
                subscription.Dispose();
            });
    }
}

By the way, it doesn't make sense to do this:

Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
            h => secondButton.Click += AnotherHandler,
            h => secondButton.Click -= AnotherHandler);

because the observable will never tick any value. You need to do this:

Observable.FromEventPattern<RoutedEventHandler, RoutedEventArgs>(
            h => secondButton.Click += h,
            h => secondButton.Click -= h);

Upvotes: 1

Related Questions