Caliburn.Micro contextual view woes or: XAML is not a purely declarative language

TLDR:
When using Caliburn.Micro in ViewModel first approach, and binding contextual content inside a view to same model (initial ViewModel), make sure to set View.Context before setting View.Model.

The long version:
This is not a criticism of Caliburn. It is really an excellent framework to speed up development, and make WPF a little less verbose for you. It did cost me quite a bit of time to get used to it and to understand it’s concepts. For same reason it’s easy to shoot yourself in the foot and find what the problem is about.

My foot wound was caused by this setup:

<ContentControl cal:View.Model="{Binding}" cal:View.Context="{Binding State}"></ContentControl>

View.Model and View.Context dependency properties provided by Caliburn.Micro. They provide us a way to host content inside a ContentControl, bind it to model provided by View.Model and select a view control depending on value of View.Context. There is seemingly nothing wrong with code above. At least for me, because I look at WPF as a declarative language. However, after running the application I get an exception:

TargetInvocationException wrapped around InvalidOperationException, stating:

“Logical tree depth exceeded while traversing the tree. This could indicate a cycle in the tree.”

at System.Windows.FrameworkElement.FindResourceInTree(FrameworkElement feStart, FrameworkContentElement fceStart, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, InheritanceBehavior&amp; inheritanceBehavior, Object&amp; source)
at System.Windows.FrameworkElement.FindResourceInternal(FrameworkElement fe, FrameworkContentElement fce, DependencyProperty dp, Object resourceKey, Object unlinkedParent, Boolean allowDeferredResourceReference, Boolean mustReturnDeferredResourceReference, DependencyObject boundaryElement, Boolean isImplicitStyleLookup, Object&amp; source)
at System.Windows.FrameworkElement.FindImplicitStyleResource(FrameworkElement fe, Object resourceKey, Object&amp; source)
at System.Windows.FrameworkElement.GetRawValue(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry&amp; entry)
at System.Windows.FrameworkElement.EvaluateBaseValueCore(DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry&amp; newEntry)
at System.Windows.DependencyObject.EvaluateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry newEntry, OperationType operationType)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry&amp; newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.InvalidateProperty(DependencyProperty dp, Boolean preserveCurrentValue)
at System.Windows.FrameworkElement.UpdateStyleProperty()
at System.Windows.TreeWalkHelper.InvalidateOnTreeChange(FrameworkElement fe, FrameworkContentElement fce, DependencyObject parent, Boolean isAddOperation)
at System.Windows.FrameworkElement.ChangeLogicalParent(DependencyObject newParent)
at System.Windows.FrameworkElement.AddLogicalChild(Object child)
at System.Windows.Controls.ContentControl.OnContentChanged(Object oldContent, Object newContent)
at MahApps.Metro.Controls.TransitioningContentControl.OnContentChanged(Object oldContent, Object newContent)
at System.Windows.Controls.ContentControl.OnContentChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex entryIndex, DependencyProperty dp, PropertyMetadata metadata, EffectiveValueEntry oldEntry, EffectiveValueEntry&amp; newEntry, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp, Object value, PropertyMetadata metadata, Boolean coerceWithDeferredReference, Boolean coerceWithCurrentValue, OperationType operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty dp, Object value)
at System.Windows.Controls.ContentControl.set_Content(Object value)

Since in my mind WPF was a advanced, nicer, smarter, better HTML, I first went after the problem in my ViewModels and code. Little did I know, problem was in the one line from beginning of this post. Order of Caliburns dependency properties was to blame. Looking more carefully, I noticed that ContentControl was getting filled with same user control which hosted it. It turns out that, though bindings give impression of declarative coding they are dependant of each other. Since View.Model was set first, Caliburn started looking for appropriate View for the model provided. Since View.Context was configured later, it defaulted to main view control. Correct declaration would be following:

<ContentControl cal:View.Context="{Binding State}" cal:View.Model="{Binding}"></ContentControl>

Asynchronously deadlocked, or Do not wrap async methods into sync wrappers (HttpClient.GetAsync not returning)

DeadlockI’m currently working on a new project which for which I decided to try out some new libraries and on the way familiarize myself a little bit better with new C# async language extensions. Even though I’ve read about the extensions, and have basic understanding of .NET task parallel libraries (which are kind of base for async extensions), it didn’t take me long to get stuck.

Application consists of ASP.NET WebAPI application which provides some data to clients, WPF client application utilizing Caliburn.Micro for presentation and some auxiliary libraries. WPF application attempts to retrieve data form WebAPI client in order to authenticate application user.  This is done using HttpClient class and WebAPI extensions of it.

While sketching out application code, things worked fine. After trying to separate code into methods, threads started getting dead locked and UI started freezing. Nothing notable has changed. Code looked something like this:

private void btnShowFoo_Click(object sender, RoutedEventArgs e)
{
    string foo = PrettyFoo();
    ShowFoo(foo);
}

public string PrettyFoo()
{
    var foo = GetFooAsync().Result;
    GiveMakeOver(foo);
    return foo;
}

public static async Task<string> GetFooAsync()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync("http://www.msdn.com");
    //    ...
}

Problem is not very easy to spot. btnShowFoo_Click calls PrettyFoo to get value which needs to be displayed. PrettyFoo in turn calls asynchronous method and waits for it result synchronously, which it then returns. This looked ok to me. It wasn’t new to me that compiled async code actually generates helper classes, callbacks and other helper things to prettify threading, but still I let this go without thinking what it actually does.

btnShowFoo_Click is executed in UI thread. When it calls PrettyFoo it blocks until called method completes and returns result. PrettyFoo asynchronously calls GetFooAsync and yields control of the thread. This is where things get interesting. Before UI thread is yielded, PrettyFoo creates continuation that will execute on UI thread, which will return result to btnShowFoo_Click. However, since btnShowFoo_Click is already blocked on UI thread, PrettyFoo‘s code which is supposed to return result waits for UI thread to be released forever. This causes UI to hang.

Since I probably didn’t do a good job explaining the problem, I suggest you read this super awesome article by Stephen Toub (Should I expose synchronous wrappers for asynchronous methods?).

Solution? It’s kind of obvious now, isn’t it? Do not wrap async methods into synchronous wrappers before thinking thrice. While we’re at that, don’t wrap sync methods into async wrappers. Stephen Toub has another excellent article on this too. If you’re thinking about using async C# language extensions, it’s a good idea to spend time to read and understand them. Seems I didn’t really understand them the first time.

How should my fixed code look like? Something like this:

private async void btnShowFoo_Click(object sender, RoutedEventArgs e)
{
    string foo = await PrettyFoo();
    ShowFoo(foo);
}

public async Task<string> PrettyFoo()
{
    var foo = await GetFooAsync();
    GiveMakeOver(foo);
    return foo;
}

public static async Task<string> GetFooAsync()
{
    HttpClient client = new HttpClient();
    HttpResponseMessage response = await client.GetAsync("http://www.msdn.com");
    //    ...
}

ABB 800xA OPC HDA reading problem

As a short foreword, it was not my intention to start a blog on a frustrating topic. I’m better at complaining about things than writing something with a more cheerful note, so this came natural to me although I tried to fight it. Still, I’m sure I’ll run into this problem again and I’d like to have this experience jotted down somewhere when I need it.

Just when I get a bit of trust in software, users and diagnostic information they provide me, I get kicked swiftly back to reality.

Yesterday I got a report that software which I maintain does not support a specific way of “addressing OPC items”. Since I’m a novice on the subject, I took this as a starting point of my debugging session. I do like when users provide me with as much information on the problem as possible, but this time taking this into account was a mistake. This OPC server (which identifies itself as ABB.AdvHtHistorySrv) provides usual OPC item tree you can browse, but items can also be addressed by an ID which contains two GUIDs and tag name. Something like this:

{EE4C1090-DE8D-47EC-A4F3-0FFABE60766C}{ABD0F369-2715-4FB4-A323-F27533E75318}:Value,Log_2s_6h

Problematic software runs as a Windows service and acts as a proxy to OPC and other data sources on behalf of other clients. It uses OPC Foundation .NET API to accomplish connection to the server. When it tied to read values, server kept returning a generic error. E_FAIL. Oooh, scarrryyy! Since this wasn’t helpful, I tried experimenting with splitting the Item ID and using it’s components as ItemName and ItemPath. No luck. Quick call to servers GetStatus() method showed server name, version and state of Down. Ok then, server is down. What’s the problem? Well, the problem is that Matrikon OPC HDA Explorer correctly reads this item.

After fiddling around some more, I decided to ignore this status and pretend I didn’t see it. Perhaps, what I should have done earlier, I called ValidateItems() method. It returned seemingly more helpful E_UNKNOWN_ITEM_NAME error. This was another sidetrack that wasted me few hours.

And then a bulb lit up over my head. Maybe it’s a security issue. Who cares that I can connect to server, that it responds to requests and tells me that item doesn’t exist. So I configured the windows service to run under same account used when testing with Matrikon OPC HDA Explorer, and voilà! It works!

To summarize this experience. Get as much information from user and diagnostics, but don’t trust it. Don’t spend your time brute forcing a solution. Rather think it out and try to solve it through reasoning, and when that inevitably fails, try things you think are unlikely.