Showing posts with label Events. Show all posts
Showing posts with label Events. Show all posts

Wednesday, 28 November 2012

Telerik Silverlight GridView click events


// Single click
this.TradesGrid.SelectionChanged += TradesGridSelectionChanged;

// Double click
this.TradesGrid.AddHandler(GridViewCellBase.CellDoubleClickEvent,
new EventHandler<RadRoutedEventArgs>(OnCellDoubleClick), true);

......

void TradesGridSelectionChanged(object sender, SelectionChangeEventArgs e)
{
if (e.AddedItems.Count == 0) return;

var trade = e.AddedItems[0] as Trade;
if (trade == null) return;

var vm = DataContext as ViewModel;
if (vm == null) return;

vm.OpenTradeForDocumenting(trade);
}

private void OnCellDoubleClick(object sender, RadRoutedEventArgs e)
{
var cell = e.Source as GridViewCell;
if (cell == null) return;

var row = cell.ParentRow as GridViewRow;
if (row == null) return;

var trade = row.DataContext as Trade;
if (trade == null) return;

var vm = DataContext as ViewModel;
if (vm == null) return;

vm.OpenTradeForDocumenting(trade);
}

Friday, 20 April 2012

Weak Event Handlers

Why would you need to use a Weak Event handler?  Take a look at this example of normal events and handlers:

image

Notice how the Console window is empty.  The Subscriber finalizer ~Subscriber() which writes to the console window has not been called meaning our subscriber is still in memory. This is due to the Publisher event holding a strong reference to the Subscribers event handler (see the watch window).

image

Why not just implement IDispose and unsubscribe from the event?

image

This is the ideal scenario but you are relying upon our Publisher being considerate enough to call dispose on the Subscriber.  This means we can remove the event handler, notice how the publishers event is now null, which means the GarbageCollector can collect our subscriber. 

But what happens if the Publisher forgets to “dispose” of the subscriber?  We still have a memory leak.

Weak Reference Events to the rescue!

image

We can see here in the watch window that the publishers event still has a reference to the subscribers event handler.  But the subscriber has been disposed…. cool!

This is all possible that to the use of a WeakReference.

Special thanks to Distin Campbell, Joe Duffy, Xavier Musy and Gregor R. Peisker.

using System;
using System.Reflection;

public delegate void UnregisterCallback<E>(EventHandler<E> eventHandler)
where E : EventArgs;

public interface IWeakEventHandler<E>
where E : EventArgs
{
EventHandler<E> Handler { get; }
}

public class WeakEventHandler<T, E> : IWeakEventHandler<E>
where T : class
where E : EventArgs
{
private delegate void OpenEventHandler(T @this, object sender, E e);

private WeakReference _targetRef;
private OpenEventHandler _openHandler;
private EventHandler<E> _handler;
private UnregisterCallback<E> _unregister;

public WeakEventHandler(EventHandler<E> eventHandler, UnregisterCallback<E> unregister)
{
_targetRef = new WeakReference(eventHandler.Target);
_openHandler = (OpenEventHandler) Delegate.CreateDelegate(
typeof(OpenEventHandler), null, eventHandler.Method);
_handler = Invoke;
_unregister = unregister;
}

public void Invoke(object sender, E e)
{
T target = (T) _targetRef.Target;

if (target != null)
_openHandler.Invoke(target, sender, e);
else if (_unregister != null)
{
_unregister(_handler);
_unregister = null;
}
}

public EventHandler<E> Handler
{
get { return _handler; }
}

public static implicit operator EventHandler<E>(WeakEventHandler<T, E> weakEventHandler)
{
return weakEventHandler._handler;
}
}

public static class EventHandlerUtils
{
public static EventHandler<E> MakeWeak<E>(this EventHandler<E> eventHandler, UnregisterCallback<E> unregister)
where E : EventArgs
{
if (eventHandler == null)
throw new ArgumentNullException("eventHandler");
if (eventHandler.Method.IsStatic || eventHandler.Target == null)
throw new ArgumentException("Only instance methods are supported.", "eventHandler");

Type weakEventHandlerType = typeof(WeakEventHandler<,>).MakeGenericType(
eventHandler.Method.DeclaringType, typeof(E));

ConstructorInfo weakEventHandlerConstructor = weakEventHandlerType.GetConstructor(
new Type[] { typeof(EventHandler<E>), typeof(UnregisterCallback<E>) });

IWeakEventHandler<E> weakEventHandler = (IWeakEventHandler<E>)weakEventHandlerConstructor.Invoke(
new object[] { eventHandler, unregister });

return weakEventHandler.Handler;
}
}

Performance


Who wants to see a shoot out between strong event handlers and our weak event handler solution?
Ok, so first up here’s the code for our benchmarks:

using System;
using System.Diagnostics;

class Performance
{
const int iterations = 1000000;

public static void Main()
{
Console.WriteLine("Running tests with {0} iterations", iterations);

RunTest("StrongEvent", new StrongEvent.Publisher());
RunTest("StrongEventDisposable", new StrongEventDisposable.Publisher());
RunTest("WeakEvent", new WeakEvent.Publisher());
}

public static void RunTest(string name, IPublisher publisher)
{
GC.Collect();
GC.WaitForPendingFinalizers();

var stopwatch = Stopwatch.StartNew();

for (int i = 0; i < iterations; i++)
{
publisher.CreateSubscriber();
publisher.DestroySubscriber();
}

stopwatch.Stop();
Console.WriteLine("{0} took {1} ms", name, stopwatch.ElapsedMilliseconds);
}
}

Results


image


Ouch!  You win some, you lose some Smile

The results are very interesting, in conclusion it really does pay to be a good .NET citizen, removing event handlers and disposing of an IDisposable wins here.

Microsoft have come up with the Weak Event Pattern for WPF: http://msdn.microsoft.com/en-us/library/aa970850.aspx
I wonder if Microsoft will come up with a better and more generic solution for weak event handlers in .NET 4.5.


Source


http://stevenhollidge.com/blog-source-code/WeakEventReference.zip

Note:  The finalizers have been commented out in the code so as not to affect the performance tests.

Thursday, 29 March 2012

WPF Interop: COM, ActiveX OCX and PDF fun

Here is an application that displays a PDF file inside a WPF window. 

To do this, the easiest way is to interop with the Adobe Reader COM ActiveX (OCX) control.

image

So how does WPF deal with COM and ActiveX (OCX controls), given the disparity between how classic Win32 and WPF handles HWNDs.

Classic Win32: One HWND per control
WPF: One HWND per window/dialog


Containers

The solution is to create:

  • a WPF window containing
  • a WindowsFormsHost control containing
  • a WinForms User Control containing
  • the ActiveX control


For our example we’ll be using the Adobe Acrobat Reader and you will need this installed if you wish to run the code and application.

Please note:
You cannot use this COM component outside of the main UI thread as the OCX is not thread-safe.

Here are the steps I took:

Add WinForms User Control

image

Add COM Reference to the project

add-COM-references

“Add Tab” to the Toolbox called Adobe, “Choose Items…” and add the Adobe PDF Reader

add-adobe-tab    choose-itemsCOM-components

You can now drag and drop the Adobe PDF Reader control from the Toolbox onto the WinForms User Control.

Drag-COM-OCX-component-to-WinFormUserControl

By dragging the control onto the surface it ensures the OCX is correctly registered by the form.

What C# code does that actually produce?

Add your code behind to the WinForms User Control

Finally, add a WindowsFormsHost control to your WPF window and add the WinForms UserControl as a child

To print just right click on the document and select Print.

Here is the same solution with a notify event raised by the WinForm User Control, to enable communication with the Wpf window:

Source code: http://stevenhollidge.com/blog-source-code/PdfViewAndPrint.zip

Source code:  http://stevenhollidge.com/blog-source-code/PdfViewAndPrint_with_event.zip

Friday, 17 February 2012

Rx Event Example

When subscribing to events Reactive Extensions (Rx) is a powerful way to filter, throttle and compose your .Net code. 

With this example I have a WPF application that listens to a FxRate pricing service, that’s pumping out 100 new prices a second via an event.

I’m going to make available the code to show how to hook up the front end Metro style application using MVVM with:

  • old skool event handlers
  • and then using Reactive Extensions (Rx)

Finally we update the Rx example to filter on just one of the exchange rates and also throttle back the rate of FxRates being received to one per second.

stockmarket-demo

The event signature

Old skool event handlers

Using MVVM, here we have my view model code stripped back just to show we have:

  • A pricing service
  • A subscribed command (data bound to the subscribed button on the UI) which toggles the subscribed property
  • A delegate (PriceUpdate) that handles the event when the subscribed button is clicked.  Click the button a second time to unsubscribe and remove the delegate from handling the event

Lines 25 and 30 show the adding and removal of the event handler, dependent on whether the user has clicked the subscribe button.

Rx Subscriptions

To do the same thing with Rx takes two lines of code (lines 18/19 and 21)

Filtering with Rx

Simply update our subscription to include a where filter that accepts the event coming in (e) and sets the predicate to Ccy (Currency) for the exchange to Euro to GBP.

Throttling with Rx

NOTE:  The code below was a workaround, please use Sample as shown here.

So we have filtered the events to only give us the Euro to GBP prices. Now let's enhance the solution just to give us the latest Euro to GBP price every two seconds.

Source code

Event handlers:  http://stevenhollidge.com/blog-source-code/standard-event-handler-wpf-metro-mvvm-stockmarket-pricing-app.zip

Reactive Extensions:  http://stevenhollidge.com/blog-source-code/Rx-wpf-metro-mvvm-stockmarket-pricing-app.zip

Tuesday, 14 February 2012

Reactive Extensions (Rx)

Overview

MSDN Definition

“Rx is a library to compose asynchronous and event-based programs using observable collections and LINQ-style query operators.”

Rx provides extension methods on top of Linq to enable developers to implement the observer pattern on query results (IEnumerables e.g. a collection or sequence).

The benefits of Rx are in it’s enabling of concurrency and it’s composability.  It allows for easy concurrent processing over a collection along with simple declarative call backs on completion and exceptions.  This programming model allows for simple orchestration of async operations.

To get familiar with Rx, in the examples below we’ll look at simple enumerations of data to get a feel for the programming style.  We can then take a look at Rx for events, with events after all just being a sequence of data (found in the EventArgs).

How To Get Reactive Extensions

Use Nuget, search for Rx and bring in the Reactive.Main library (System.Reactive namespace).

rx-Nuget

Simple example

1.Convert the linq query into an observable (using the Rx extension method).

2. Write a delegate which will execute for:

  • Each item in the enumeration (OnNext method in the examples below)
  • When an error occurs (OnError method in the examples below)
  • When the enumeration completes (OnCompleted method in the examples below)

3. Subscribe to the query results.  This is whether you hook up each of your delegates and start the enumeration.

rx-Simple

“Finally” delegate

There is another delegate we can set, that runs after the processing has completed, regardless of whether the enumeration successfully got the end of the sequence or not e.g. An error occurred half way through processing so the completed delegate doesn’t run.  The Finally delegate will always run which might be useful for clean up.

rx-FinallyDelegate

How to Configure Threading

rx-HowToConfigureThreads

Notice how all the "getting" and "processing" are sequential and in keeping with the enumeration (within each group) even though the processing might be occurring on different threads.

Early Cancellation of Processing

You can cancel the processing of a collection, here is an example:

rx-EarlyCancellation

“Using” A Disposable Object

This example code disposes of an object after the completed delegate has run.

rx-UsingDisposableObjects

A real world example may look like this:

Demo Source Code

You can download the demo here:  http://stevenhollidge.com/blog-source-code/RxExtensionsDemo.zip

Friday, 26 August 2011

Threadsafe Events in .Net

Usually the event pattern used by C# devs would be something long these lines:

When actually this provides for a cleaner threadsafe implementation:

Thanks to Rob Eisenberg for the suggestion!

Remember the event keyword is just a modifier for a delegate declaration that allows it to be included in an interface, constraints it invocation from within the class that declares it, provides it with a pair of customisable accessors (add and remove) and forces the signature of the delegate (Object sender, EventArgs e).