Friday, September 23, 2011

Heisenbugs! Schrödinbugs! Multi-Threading Programming, Quantum Mechanics, and You!

My team leader has a saying for strange bugs popping up -- Heisenbugs.  Your code is correct.  Everything should be fine.  However, for some reason...  BOOM!  Exception.  You lose some hair.  I think a more appropriate name is Schrödinbugs, though.  They appear to be correct and if you step through them, they'll work.  However, the second you stop observing them, they always seem to have the potential for a different result.  Ahhh...  unpredictability!

This is frustrating, but I've noticed one of the biggest problems generally stems from multi-threading.  Most developers aren't tuned to developing multi-threaded applications.  Even when they are, it's just another thing to watch out for when developing code.

So, you may be writing an application in WPF.  Say, it subscribes to an asynchronous TCP socket at the application level.  You have a callback on a user control.  Is there a potential problem?

YES.

Any time you have another resource that can act of its own accord and interface with another thread (events to the user interface, for example), you have a chance of having a Schrödinbug!  For example, at work I had a strange issue -- a control would hit the end of its life-cycle.  Disposed and all was well, right?  Well, not quite.  I had a DispatcherTimer that was syncing up some things for that control.  I stopped it in Dispose -- so the timer shouldn't be called, right?

Wrong.

The timer did stop -- but it had already entered its callback on the event thread.  The thread then swapped back to handle the Dispose that I had called.  It finished the Dispose, then went back to the event callback to finish.  Surprise surprise!  The control had been disposed and threw an exception.  So, how do we get around this?

I've developed a fairly simple pattern...  using a lock and the basic Disposable pattern.  I'm attaching the basic skeleton on how to implement this in your code:


    public class MyClass : IDisposable
    {  
        private object _lock = new object();
 
        #region IDisposable Pattern
 
        private Boolean _disposed = false;
 
        private void OnEventCallback(object sender, EventArgs e)
        {
            lock(_lock)
            {
                if( _disposed)
                    return;
 
                // Handle callback here
            }
        }
 
        /// <summary>
        /// When called, throws an ObjectDisposedException if the object has been disposed.
        /// </summary>
        protected virtual void CheckDisposed()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }
        }
 
        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
 
        /// <summary>
        /// Core dispose methods
        /// </summary>
        /// <param name="disposing">True if called from IDisposable::Dispose</param>
        protected virtual void Dispose(bool disposing)
        {
            lock (_lock)
            {
                if (disposing && !_disposed)
                {
                    // Clean up managed resources here
                }
 
                _disposed = true;
            }
        }
 
        /// <summary>
        /// Releases unmanaged resources and performs other cleanup operations before the
        /// <see cref="MyClass"/> is reclaimed by garbage collection.
        /// </summary>
        ~MyClass()
        {
            Dispose(false);
        }
 
        #endregion
    }


Notice the lock around the two most important parts -- I wanted to make sure that I have critical sections on the _disposed, such that I can break out as necessary.  Notice, if it enters the thread for the callback, we're fine.  If it disposes on the other thread, we can still break out before the code hits something disposed.  Essentially, we're making textbook critical sections and managing them appropriately.

Nothing unusual or entirely special -- just adapted to be mindful of another thread.

Wednesday, September 7, 2011

Control Lifecycle Gotcha's in Silverlight

I've come acrosss some more "fun" in Silverlight.  One of the most irritating (and not very well documented) pieces involves the tear-down and destruction of your controls.  Creation of controls is pretty simple, with a few caveats.

Control Creation


When a control or page is created in Silverlight, if the child controls are not visible, they are not "created."  Rather, they are created when they become visible.  For instance, if you have a Container control of some kind (Grid, etc) that is Collapsed, all of the child controls will not be created until it becomes visible.  Given how the rendering/layout engine works in WPF and Silverlight, this kind of makes sense -- only worry about what is visible.

Control Teardown and Destruction


The Unloading event occurs in a different order.


This is the most irritating part for me, as a developer.  Primarily because it doesn't make a whole lot of sense to me and is rather different compared to other frameworks.

Let's start with what we would think should happen, normally.  Supposing you had controls each in a hierarchy of:

A is the parent of B, which is the parent of C.

You would think C gets Unloaded first, then B, then A.

It's the exact opposite.

A is Unloaded, then B, then C.

If you have something, for instance, at point B that needs to be taken care of before C, you'll have some very frustrating issues ahead of you.  For example, C may consume resources that are created in B (such as a service).  Suppose the control is closed, B will attempt to clean up its resources before C does (assuming you've built your controls cleanly).  So, if C is still trying to access the resource created at the scope of B...  C will blow up with all kinds of exceptions.

Finalizers are called upon Application exit.

Not much to be said here -- whereas WPF and WinForms call finalizers generally as soon as the references disappear, Silverlight nukes them upon Application exit.  So, if you want to free up resources, you need to do that beforehand.

In Closing

In short, writing Silverlight is a bit more complicated and doesn't handle things quite as easily as other frameworks we're used to.  However, knowing the afore mentioned, you should be able to make your code cleaner and more efficient.

Tuesday, September 6, 2011

'x' was already registered by 'y' in Silverlight and WPF

So, I've had the extreme pleasure of working with a lot of Silverlight recently -- and my code in WPF had never been tested with multiple controls (stupid me).  When I did, I got all kinds of errors about properties not being set correctly, and eventually, after commenting out enough, I received the error

"'X' was already registered by 'Y.'"

So looking deeper, I notice it always happens on the second element.  Weird.  Looking further, I notice that my DependencyProperty pattern is basically declared at a private-instance level, i.e.:
DependencyProperty TitleProperty = DependencyProperty.Register("Title"typeof(string), typeof(SomeControl), new PropertyMetadata(string.Empty));
In Silverlight, this isn't a big deal.  In WPF, it's a deal-breaker.  It appears that Silverlight can automatically handle instance-level dependency properties (or more likely, translating bad code into them).  In WPF, it's not as forgiving and needs to be prefaced by:
public static readonly 
i.e.,
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title"typeof(string), typeof(SomeControl), new PropertyMetadata(string.Empty));

With that, everything works again and my Silverlight code doesn't break either.

Interesting difference between WPF and Silverlight, for sure.