Over a million developers have joined DZone.

Debugging binding issues is hard. Having simpler code makes it easier.

· Performance Zone

Evolve your approach to Application Performance Monitoring by adopting five best practices that are outlined and explored in this e-book, brought to you in partnership with BMC.

Recently I had to deal with a strange bug.
Sometimes the menu option to create a secondary tile was not being enabled when it should be.
After analysis I was able to get the most consistent reproduction of the issue on a lower spec device (a Lumia 620). Obviously this isn't acceptable so a solution had to be found.

I tracked the most likely candidate to the `CanPin()` method. You can see the "before" version below.
You'll notice that it "smells" of all sorts of issues. It's also not something that can be debugged or instrumented easily.
It also isn't immediately obvious how it works because it's not easy to read.

internal bool CanPin()
    return !this.IsPinned()
        && this.UnderlyingModel != null
        && !this.IsRunningInKidsCorner()
        && (this.UnderlyingModel.IsSpecial
         || string.IsNullOrWhiteSpace(this.UnderlyingModel.ArtUrl)
         || (!string.IsNullOrWhiteSpace(this.UnderlyingModel.ArtUrl)
          && this.imageCacher.IsCached(this.UnderlyingModel.ArtUrl)));
There's definitely the possibility for something funny to be going on there.
Could all those checks be being made in an order differently to how they're listed?
Could there be a bug in the logic?
Could the time it takes for them to be run be taking longer than is available to trigger the binding to update?

The only option available is to refactor to make the method clear about what it does and in what order.
internal bool CanPin()
    if (this.IsPinned())
        Debug.WriteLine("Cannot pin as already pinned");
        return false;

    if (this.UnderlyingModel == null)
        Debug.WriteLine("Cannot pin as don't have the underlying model (needed when generating the image and deep link path)");
        return false;

    if (this.IsRunningInKidsCorner())
        Debug.WriteLine("Cannot pin as running in kids corner");
        return false;

    if (this.UnderlyingModel.IsSpecial)
        Debug.WriteLine("CAN pin as is special (will use special artwork)");
        return true;

    if (string.IsNullOrWhiteSpace(this.UnderlyingModel.ArtUrl))
        Debug.WriteLine("CAN pin as has no artwork (default/fallback will be used)");
        return true;

    if (this.imageCacher.IsCached(this.UnderlyingModel.ArtUrl))
        Debug.WriteLine("CAN pin as artwork has been cached");
        return true;

    Debug.WriteLine("Cannot pin as all tests failed");
    return false;

And, as if by magic the problem went away.

So what was the problem?
I can't be 100% certain.
But I'm not sure that matters.
That well written, easily understandable code doesn't display unexpected, unintended consequences--that's a good thing. Why badly written, hard to undertand code has certain unintended consequences--isn't a priority for me just now.

This leads me to be reminded of three important lessons:
- Debugging binding issues is hard (Bind to simple properties to help avoid binding issues.)
- Simple code is better (both to debug and to maintain)
- Be sure to test on real devices (both low and high spec)

Bind to simple properties to help avoid binding issues.
Write code that is easy to read so it's easier to maintain in the future.

Learn tips and best practices for optimizing your capacity management strategy with the Market Guide for Capacity Management, brought to you in partnership with BMC.


Published at DZone with permission of Matt Lacey, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}