Part 1
Yesterday I went back to my customer, tried to figure out if the whole concept of using data as the content of a ContentControl instead of holding a logical tree, is truly contribute to the whole system, and guess what? It is not!
Well it figured out that setting the content property with non-visual element only postponed the tree-traversal. We figured this out by trying to measure the total elapsed time between setting the content property to null and up until the view completely disappeared.
To measure this we called the Dispatcher.BeginInvoke method with Background priority. Note that I used different set of controls to put more pressure and to turn the Dispatcher.BeginInvoke invocation time negligible.
The results showed us that the direct technique is a little bit faster in total time, but much slower when setting the content property (in our case the total time is more important).
private void Button_Click(object sender, RoutedEventArgs e)
{
if (_placeholder.Content != null)
{
Stopwatch stopWatch = Stopwatch.StartNew();
_placeholder.Content = null;
long setContentTime = stopWatch.ElapsedMilliseconds;
Dispatcher.BeginInvoke(
DispatcherPriority.Background, (Action)delegate
{
stopWatch.Stop();
long unloadViewInclusiveTime = stopWatch.ElapsedMilliseconds;
long unloadViewExclusiveTime = unloadViewInclusiveTime - setContentTime;
LogTime(setContentTime, unloadViewInclusiveTime, unloadViewExclusiveTime);
});
}
}
private static void LogTime(
long setContentTime,
long unloadViewInclusiveTime,
long unloadViewExclusiveTime)
{
Debug.WriteLine(string.Format(
"Time to set ContentControl.Content property: {0}ms.", setContentTime));
Debug.WriteLine(string.Format(
"Exclusive Time to unload view: {0}ms.", unloadViewExclusiveTime));
Debug.WriteLine(string.Format(
"Inclusive Time to unload view: {0}ms.", unloadViewInclusiveTime));
}
This conclusion lead us to think of another way to reduce the unload overhead. So I came out with the following simple solution: Instead of using ContentControl as the view place holder, use Border!
Surprisingly or not, here are the results:
| Direct | Indirect | Efficient |
| 84 | 101 | 56 |
| 90 | 105 | 64 |
| 84 | 120 | 73 |
| 77 | 104 | 62 |
| 86 | 98 | 71 |
| 91 | 101 | 64 |
| 106 | 108 | 70 |
| 104 | 128 | 66 |
| 93 | 115 | 66 |
| 90 | 110 | 63 |
| Average 90.5 | Average 109 | Average 65.5 |
* Efficient is the Border test
As you can see in the table above, it looks like using a Border is somehow much faster than using a ContentControl.
Here is my tester.