{"id":3357,"date":"2015-09-13T21:41:56","date_gmt":"2015-09-13T21:41:56","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=3357"},"modified":"2015-09-13T21:41:56","modified_gmt":"2015-09-13T21:41:56","slug":"observable-fromeventpattern-discussed","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/observable-fromeventpattern-discussed\/","title":{"rendered":"Observable.FromEventPattern discussed"},"content":{"rendered":"<p>I was actually looking through my past blog posts and noticed I&#8217;ve never published anything on Reactive Extensions (Rx). I actually have a draft &#8220;beginners&#8221; guide which I started a couple of years back, but never completed, so I may end up publishing that at a later date.<\/p>\n<p><em>Note: The best resource for Rx information that I&#8217;ve found is <a href=\"http:\/\/www.introtorx.com\/\" target=\"_blank\">Introduction to Rx<\/a>, I&#8217;d definitely recommend you visit that site for complete and excellent documentation on Rx.<\/em><\/p>\n<p>Okay, for this post I&#8217;m just going to focus on the FromEventPattern. Even though the syntax is pretty simple I have a habit of forgetting it everytime I come to use it, so as this blog is about refreshing my memory, I thought I&#8217;d write a blog post dedicated to this method.<\/p>\n<p><strong>Why use Rx instead of handling events in the conventional way?<\/strong><\/p>\n<p>One of the most obvious reasons to use Rx to handle events is that it can help stop those pesky memory leaks when we forget to unsubscribe to an event. Another reason is the IObservable returned from FromEventPattern is composable and we can filter events that we&#8217;re not interested in and\/or marshal events from one thread onto another &#8211; for example when events are coming from a worker thread we might marshal them onto the UI thread.<\/p>\n<p>Take a look at <a href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/system.reactive.linq.observable.fromeventpattern(v=vs.103).aspx\" target=\"_blank\">Observable.FromEventPattern Method<\/a> to see the current syntax\/overloads for this method. <\/p>\n<p>I will not be covering all the overloads here but will instead look at the three I&#8217;ve used the most. So let&#8217;s get started&#8230;<\/p>\n<p><strong>FromEventPattern with an EventHandler which takes no EventArgs<\/strong><\/p>\n<p>In some cases you might have an event handler which doesn&#8217;t use EventArgs, for example<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic event EventHandler Reverted;\r\n<\/pre>\n<p>in such a case we use the overload<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static IObservable&lt;EventPattern&lt;EventArgs&gt;&gt; FromEventPattern(\r\n\tAction&lt;EventHandler&gt; addHandler,\r\n\tAction&lt;EventHandler&gt; removeHandler)\r\n<\/pre>\n<p>So our code might look like this<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar o = Observable.FromEventPattern(\r\n   x =&gt; domainObject.Changed += x,\r\n   x =&gt; domainObject.Changed -= x).\r\n   Subscribe(_ =&gt; DoSomething());\r\n<\/pre>\n<p><strong>FromEventPattern with standard event patterns (using the EventHandler class)<\/strong><\/p>\n<p>Building on the previous syntax&#8230;<\/p>\n<p>In many cases, where the events that we want to subscribe to, use the &#8220;standard .NET event pattern&#8221;, (for example where the handler takes an EventArgs derived class) and were declared using the syntax<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic event EventHandler&lt;CellsInViewChangedEventArgs&gt; CellsInViewChanged;\r\n<\/pre>\n<p>we will use this overload. Note: This version expects an EventHandler<> object.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static IObservable&lt;EventPattern&lt;TEventArgs&gt;&gt; FromEventPattern&lt;TEventArgs&gt;(\r\n\tAction&lt;EventHandler&lt;TEventArgs&gt;&gt; addHandler,\r\n\tAction&lt;EventHandler&lt;TEventArgs&gt;&gt; removeHandler\r\n)\r\nwhere TEventArgs : EventArgs\r\n<\/pre>\n<p>To use this we simple supply the EventArgs derived type, for example<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar o = Observable.FromEventPattern&lt;CellsInViewChangedEventArgs&gt;(\r\n   x =&gt; grid.CellsInViewChanged += x,\r\n   x =&gt; grid.CellsInViewChanged -= x).\r\n   Subscribe(_ =&gt; DoSomething());\r\n<\/pre>\n<p><strong>FromEvent pattern with standard event patterns (not using the Event Handler class)<\/strong><\/p>\n<p>Finally, for this post, in some cases we have events which do not use the EventHandler<> class, for example the WPF RoutedEvents use <\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic delegate void RoutedEventHandler(\r\n   object sender, \r\n   System.Windows.RoutedEventArgs e)\r\n<\/pre>\n<p>In such cases we need to supply both the Delegate type and EventArgs type to the FromEventPattern, hence we use the syntax<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static IObservable&lt;EventPattern&lt;TEventArgs&gt;&gt; FromEventPattern&lt;TDelegate, TEventArgs&gt;(\r\n\tAction&lt;TDelegate&gt; addHandler,\r\n\tAction&lt;TDelegate&gt; removeHandler\r\n)\r\nwhere TEventArgs : EventArgs\r\n<\/pre>\n<p>our code will now look like this<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar o = Observable.FromEventPattern&lt;RoutedEventHandler, RoutedEventArgs&gt;(\r\n   x =&gt; button.Click += x,\r\n   x =&gt; button.Click -= x).\r\n   Subscribe(_ =&gt; DoSomething());\r\n<\/pre>\n<p><strong>More&#8230;<\/strong><\/p>\n<p>I don&#8217;t intend to cover all the possible uses of the IObservable which is returned by the FromEventPattern, but suffice to say (as mentioned earlier). We can ensure events are marshaled onto the thread which created the observable, so for example if we create this from the UI thread we can write<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nvar o = Observable.FromEventPattern&lt;ValuesChangedEventArgs&gt;(\r\n   x =&gt; server.ValuesChanged += x,\r\n   x =&gt; server.ValuesChanged -= x).\r\n   ObserveOn(SynchronizationContext.Current).\r\n   Subscribe(_ =&gt; DoSomething());\r\n<\/pre>\n<p>here, the ObserveOn will ensure that the events that might be coming from a worker thread are marshaled onto the current thread. Obviously if this was created on the UI thread this will marshal back onto that thread.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I was actually looking through my past blog posts and noticed I&#8217;ve never published anything on Reactive Extensions (Rx). I actually have a draft &#8220;beginners&#8221; guide which I started a couple of years back, but never completed, so I may end up publishing that at a later date. Note: The best resource for Rx information [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-3357","post","type-post","status-publish","format-standard","hentry","category-reactive-extensions"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/3357","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=3357"}],"version-history":[{"count":7,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/3357\/revisions"}],"predecessor-version":[{"id":3383,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/3357\/revisions\/3383"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=3357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=3357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=3357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}