duminică, 31 octombrie 2010

[1][1] Routed Events

[1][1] Routed Events


  • Events in WPF are called routed because there is a brand new process to handle these events.
  • In WPF, the parent element can provide information to child elements, providing usage, customization, and visibility to the potentially smaller, nested objects.
  • Instead of just calling handlers attached to the element that raised the event, WPF walks the tree of user interface elements, calling all handlers for the routed event attached to any node from the originating element right up to the root of the user interface tree.
  • The C# compiler would generate a hidden private field to hold the event handler, meaning that you pay a per-object overhead for each event whether or not any handlers are attached.
  • There are three types of routed events:
    • Tunneling
      • It fires in the opposite direction from the top of the visual tree down.
      • Tunneling events can be easily identified because, by convention, they are named with a Preview prefix
    • Bubbling
      • It provides event handling from the originating element of a visual tree to the root of the tree.
    • Direct
      • Direct events represent the typical approach to which .NET programmers
  • To suppress the handling of an event, you need to set that Handled property of the RoutedEventArgs parameter

private void PreviewMouseDownButton(object sender, RoutedEventArgs e)
{
    e.Handled = true;
}

    • Although setting the RoutedEventArgs parameter’s Handled property to true in a routed event handler appears to stop the tunneling or bubbling, individual handlers further up or down the tree can opt to receive the events anyway
    • This can only be done from procedural code, using an overload of AddHandler that adds a Boolean handledEventsToo parameter
    • If you set the Handled flag in a Preview handler, not only will the tunneling of the Preview event stop, but also the corresponding bubbling event that would normally follow will not be raised at all.
  • Find the Source Element in an Event Handler: you need to access the Source property of the RoutedEventArgs parameter
  • These are the properties of RoutedEventArgs that are most useful:
    • Source—The element in the logical tree that originally raised the event.
    • OriginalSource—The element in the visual tree that originally raised the event
    • Handled
    • RoutedEvent—The actual routed event object (such as Button.ClickEvent), which can be helpful for identifying the raised event when the same handler is used for multiple routed events.
  • Routed events are represented as public static RoutedEvent fields with a conventional Event suffix
  • The routed event is registered much like a dependency property in the static constructor and a normal .NET event—or event wrapper—is defined to enable more familiar use from procedural code and adding a handler in XAML with event attribute syntax
    • There are used AddHandler and RemoveHandler.
      • These methods are inherited from System.Windows.UIElement
    • static Button()
      {
      // Register the event
      Button.ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Button));
      }
      // A .NET event wrapper (optional)
      public event RoutedEventHandler Click
      {
      add { AddHandler(Button.ClickEvent, value); }
      remove { RemoveHandler(Button.ClickEvent, value); }
      }
      protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
      {

      // Raise the event
      RaiseEvent(new RoutedEventArgs(Button.ClickEvent, this));
      }

  • Most of the bubbling events are used in pair with tunneling event
    • The idea behind having a pair of events for various activities is to give elements a chance to effectively cancel or otherwise modify an event that’s about to  occur.

Attached Events

  • This is the routed-event equivalent of an attached property: an event defined by a different class than the one from which the event will be raised.
  • It keeps system open for extension

  • <Grid Mouse.PreviewMouseDown="PreviewMouseDownGrid" Mouse.MouseDown="MouseDownGrid">
  • The code behind it is :
    _grid.AddHandler(Mouse.PreviewMouseDownEvent, new MouseButtonEventHandler(PreviewMouseDownGrid));
    _grid.AddHandler(Mouse.MouseDownEvent, new MouseButtonEventHandler(MouseDownGrid));

    or

    Mouse.AddPreviewMouseDownHandler(_grid, PreviewMouseDownGrid);
    Mouse.AddMouseDownHandler(_grid, MouseDownGrid);


Mouse Inputs


Event
Routing
Meaning
GotMouseCapture
Bubble
Element captured the mouse.
LostMouseCapture
Bubble
Element lost mouse capture.
MouseEnter
Direct
Mouse pointer moved into element.
MouseLeave
Direct
Mouse pointer moved out of element.
PreviewMouseLeftButtonDown, MouseLeftButtonDown
Tunnel, Bubble
Left mouse button pressed while pointer inside element.
PreviewMouseLeftButtonUp, MouseLeftButtonUp
Tunnel, Bubble
Left mouse button released while pointer inside element.
PreviewMouseRightButtonDown, MouseRightButtonDown
Tunnel, Bubble
Right mouse button pressed while pointer inside element.
PreviewMouseRightButtonUp, MouseRightButtonUp
Tunnel, Bubble
Right mouse button released while pointer inside element.
PreviewMouseDownMouseDown
Tunnel, Bubble
Mouse button pressed while pointer inside element (raised for any mouse button).
PreviewMouseUpMouseUp
Tunnel, Bubble
Mouse button released while pointer inside element (raised for any mouse button).
PreviewMouseMove, MouseMove
Tunnel, Bubble
Mouse pointer moved while pointer inside element.
PreviewMouseWheel, MouseWheel
Tunnel, Bubble
Mouse wheel moved while pointer inside element.
QueryCursor
Bubble
Mouse cursor shape to be determined while pointer inside ele

      

marți, 26 octombrie 2010

Visitor Pattern

Visitor Pattern

About

  • defines and performs new operations on all the elements of an existing structure, without altering its classes
  • the visitor design pattern is a way of separating an algorithm from an object structure it operates on
  • using the visitor pattern allows to conform with the open/closed principle
    • "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification"
    • inheritance
    • use interfaces/abstract classes -- change the implementation if it is needed / multiple implementation could be created


Client:
  • initiate and manage the element (objectStructure)
  • Call Visitor methods on objectStructure
Visitor:
  • Classes that contain methods that iterate through the object structure and apply operations to its elements
Element1, Element2
implements an Accept operation that takes a visitor as an argument

class ConcreteElementA : Element
{
  public override void Accept(Visitor i_visitor)
  {
    visitor.VisitElement1(this);
  }
...
}


Samples:
  • Animals that do different things: barks, run, ...
  • Different operation (getWage(), getPTO() ) on different type of employees (manager, programmer, tester)

Visitor Pattern in C#:

  • System.Reflection API
    • Viewing metadata
    • Performing type discovery
    • Late binding to methods and properties
    • Creating types at runtime with Reflection.Emit
            Type[]: Will hold a list of type names
            GetType( )Will return a class name
            MethodInfoCan return all parameters and the return type of a method
            InvokeWill call the method described in a variable of type MethodInfo

  • Use Visitor Pattern to do different operation on tree (binary tree)

Shortcomings of the Visitor pattern

  • The return type of visiting methods have to be known in advance. 
  • A lot of code has to be written to prepare the use of visitors: the visitor class with one abstract method per class, and a accept method per class. This code is tedious and boring to write. 
  • If a visitor pattern has not been written in the first time, the hierarchy has to be modified to implement it.

vineri, 8 octombrie 2010

Comparison between .NET Memory Profiler 3.5 (SciTech) - ANTS Memory Profiler 6.0

Comparison between .NET Memory Profiler 3.5 (SciTech) - ANTS Memory Profiler 6.0



Both tools

  • work with memory snapshots
  • can make difference between snapshots
  • give information about the:
    • live instance
    • instance difference (between snapshots)
  • you have info related to types that are reference and the types that are referred by another type (instance)
  • you have details related to type instance
  • Integration with Visual Studio
  • Time to save a session is consistent


.NET Memory Profiler 3.5 (SciTech)

  • Even you can set filters for memory snapshot the time needed to take a snapshot was about 3 hours
  • You can attached to an existing process (with ANTS Memory Profiler 6.0 seems that you can attached only to a .NET 4 process)
  • Even, you can start an executable, in my case, starting IxNetwork from SciTech tool has seldom succeeded (almost of time starting IxNet failed)
  • You can filter objects by name and by namespace
  • It gives some information related to Direct/Indirect Event Handler roots, Direct/Indirect Delegate roots (these roots are more likely to be the root of a leak)
    • it is better highlight the object with problems
    • also, you have the chance to see which instance are with problem/s
  • You can see instance values at a moment
  • Check the memory usage


ANTS Memory Profiler 6.0

  • Time to take a snapshot: 1-2 minutes
  • Visualization tools are much better (diagrams, graphs)
    • easy to identify the root object that it is keeping a reference (to an event handler for example)
    • Easy to navigate to the objects that refers an instance type of to object that are referred by an instance type (SciTech tool is not so “user friendly” in this case)
    • easy to see referenced object/ object that refer that object (a graph) -- in SciTech tool there is a tab system and it is a annoying to navigate between tabs.
    • In my case there were some issues with AutoResetEvent. With this tool, I have found the root object that keeps those events in less then 5 minutes. With SciTech tool, when I have analyzed the root object for this event, I have come to have some supposition and not a clear picture of the problem.
  • You can filter object by name (full name)
  • It is working harder when you apply filters (in SciTech tool this operation are working a little bit faster)
  • I had some failures with saving a session
  • Save pics/pdf files for a diagram (that, for example, identifies a leak)
  • No way to cancel a snapshot (in my case, the application has crashed, but the snapshot appeared that it is still collecting data. I have to close the the ANTS application).



From ANTS Memory Profiler 6.0 web page

  • Obtain clear, meaningful results
  • Get results fast – With a footprint of less than 32 MB (With SciTech tool the session (compose of 2 snapshots) is about 300 MB)
  • Quickly visualize the relationship between your objects
  • Summary information
  • Powerful filtering options to narrow your search down to the objects you really need to know about. Standard object filters and advanced object filters available.
  • Supports .NET 1.1 to .NET 4.0

joi, 7 octombrie 2010

DispatcherTimer

DispatcherTimer

About

  • A timer that is integrated into the Dispatcher queue which is processed at a specified interval of time and at a specified priority.
  • It raise time notification using Dispatcher class
  • Timers are not guaranteed to execute exactly when the time interval occurs.
  • If a System.Timers.Timer is used in a WPF application, the System.Timers.Timer runs on a different thread then the user interface (UI) thread.
    • In order to access objects on the user interface (UI) thread, it is necessary to post the operation onto the Dispatcher of the user interface (UI) thread using Invoke or BeginInvoke.
  • priority field- used with constructor: you can set it DispatcherPriority.Background priority

Sample



private readonly DispatcherTimer m_dispatcherTimer;

ctor
{
  
     m_dispatcherTimer = new DispatcherTimer(DispatcherPriority.Background, Dispatcher)
                                    {Interval = new TimeSpan(0, 0, 0, 0, 300)};
}

         private void Start()
         {    
             Stop();
             m_dispatcherTimer.Tick += DispatcherTimer_Tick;
             m_dispatcherTimer.Start();
         }

         private void Stop()
         {
            m_dispatcherTimer.Stop();
            m_dispatcherTimer.Tick -= DispatcherTimer_Tick;
        }

        private void DispatcherTimer_Tick(object sender, EventArgs e)
        {
            //do something ...
        }

        private static void IsRunningPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if ((bool)e.NewValue)
            {
                Start();
            }
            else
            {
                Stop();
            }
        }

        public bool IsRunning
        {
            get { return (bool)GetValue(IsRunningProperty); }
            set { Dispatcher.BeginInvoke(new Action(() => SetValue(IsRunningProperty, value))); }
        }
       public static readonly DependencyProperty IsRunningProperty =
            DependencyProperty.Register("IsRunning", typeof(bool), typeof(ProgressCtrlData), new UIPropertyMetadata(false));



References:
Chris Sells and Ian Griffiths, "Programming WPF", SECOND EDITION, O’Reilly Media


  

luni, 4 octombrie 2010

[3][2]System.Threading.DispatcherObject

[3][2]System.Threading.DispatcherObject

  • Most objects in WPF derive from DispatcherObject, which provides the basic constructs for dealing with concurrency and threading.
  • It is the base class for any object that wishes to be accessed only on the thread that created it
  • WPF is based on a messaging system implemented by the dispatcher
  • WPF dispatcher uses User32 messages for performing cross thread calls.
  • Thread affinity happens when a component uses the identity of the executing thread to store some type of state. The most common form of this is to use the thread local store (TLS) to store state. Thread affinity requires that each logical thread of execution be owned by only one physical thread in the operating system, which can become memory intensive. In the end, WPF’s threading model was kept in sync with the existing User32 threading model of single threaded execution with thread affinity.
    • WPF requires Single Threaded Apartment (STA) threading, so you must apply a [System.STAThread()] attribute to your Main method.
  • The dispatcher is a basic message dispatching system, with multiple prioritized queues. Examples of messages include raw input notifications (mouse moved), framework functions (layout), or user commands (execute this method).
  • DispatcherObject defines a Dispatcher property (of type Dispatcher) containing several overloads of Invoke (a synchronous call) and BeginInvoke (an asynchronous call).
    • BeginInvoke has no corresponding EndInvoke
    • To know when an async operation is finished we can use DispatcherOperation class
    • Dispatcher.BeginInvoke method returns a DispatcherOperation object
      • Status property of type DispatcherOperationStatus enumeration (Pending, Executing, Completed, Aborted)
      • DispatcherOperation.Abort method
  • method
  • CheckAccess method returns true if you are on the correct thread, false otherwise.
  • VerifyAccess method is intended for when you think you are already on the right thread, and it would be indicative of a problem in the program if you were not. 
    • It throws an exception if you are on the wrong thread.
    • It used by many WPF type when they are used
  • The Dispatcher class:
    • it lives in the System.Windows.Threading namespace
    • it defines a Dispatcher property, which returns the Dispatcher object for the thread to which the object belongs
    • Dispatcher.CurrentDispatcher static property
    • Dispatcher.Wait method: wait for the operation to complete

References: 
Chris Sells and Ian Griffiths, "Programming WPF", SECOND EDITION, O’Reilly Media
Adam Nathan, "Windows Presentation Foundation Unleashed", Sams Publishing