Tuesday, 18 June 2013

Unsubscribing to Observables using IDisposable

In continuation to my last post, now we have requirement that the subscription should be disposed as soon as the word count reaches 10.

So the new behavior should be something like:-



Note that the textblock only copies 10 items and then unsubscribes. This can be done using the instance of IDisposable that is returned when we do a subscription. In previous examples we just ignored them.


Now the new C# code will look like:-

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            var textChangedEvent = Observable.FromEventPattern(txtWord, "TextChanged");
         
            var disposable = textChangedEvent.Subscribe(_ => txtBlock.Text = txtWord.Text);

            textChangedEvent.Subscribe(_ =>
                {
                    var count=txtWord.Text.Split(' ').Count();
                    this.Title = "Word Count= " + count;
                    if(count>=10)
                        disposable.Dispose();
                }
                );
        }


Now this thing has started pleasing me. Rx is all over me and if I be imaginative, I know it has numerous applications? Are you with me? Hey wait.. this is just the beginning. Rx is much more powerful.

Rx makes things easy by allowing us to do operations on observables. Suppose your manager comes to you and asks you to change the above code so that text in textbox will get copied to textblock only when user has finished writing a word or a sentence (i.e. when a space or full stop is encountered). No problem, the changed code should look like:-

        private void Window_Loaded_1(object sender, RoutedEventArgs e)
        {
            var textChangedEvent = Observable.FromEventPattern(txtWord, "TextChanged");
         
            var disposable = textChangedEvent.Subscribe(_ =>
                {
                    if (txtWord.Text.ToCharArray().Last() == ' ' || txtWord.Text.ToCharArray().Last() == '.')
                        txtBlock.Text = txtWord.Text;
                }
               );

            textChangedEvent.Subscribe(_ =>
                {
                    var count=txtWord.Text.Split(' ').Count();
                    this.Title = "Word Count= " + count;
                    if(count>=10)
                        disposable.Dispose();
                }
                );
        }
    }


Then he comes back and asks you to copy texts only after every 2 seconds. For this, Rx provides another cool extension method called throttle. Stay tuned...


No comments:

Post a Comment