Windows Phone 7 – High Performance Code Behind Default Layout
Posted by: | Technical |
Not sure why it’s not the default, but this is the recommended way to have a good performant Windows Phone 7 page. Notice how the LayoutUpdated event is used once to ensure the first frame is drawn before we do any heavy lifting.
see Windows Phone Performance Whitepaper here for more
Note that this isn’t strictly required of course, but if you are going to iso storage or calling a web service and such like you really don’t want to be doing that in Loaded event or in OnNavigatedTo, as the page might well not show for a while.
public partial class MainPage : PhoneApplicationPage
{
private bool _onNavigatedToCalled = false;
public MainPage()
{
InitializeComponent();
LayoutUpdated += new EventHandler(View_LayoutUpdated);
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_onNavigatedToCalled = true;
}
void View_LayoutUpdated(object sender, EventArgs e)
{
if (_onNavigatedToCalled)
{
_onNavigatedToCalled = false;
Dispatcher.BeginInvoke(() =>
{
// spin off the heavy lifting here
}
);
}
}
}
Additionally, you might want to use a BackgroundWorker or full-on Thread.Start inside the LayoutUpdated event handler so that your UI isn’t blocked further.
Coupled with the lovely MVVM pattern, this can result in great-looking just-in-time loading as ViewModel properties are updated and the View “fills-in” when the data is ready.
Dispatcher.BeginInvoke will help to speed things up but yes, still on same thread, a BackGroundWorker would make things even more responsive;)
I’m going to post this up for the Caliburn Micro people to see if there’s anyway we can get this baked in.
There is currently an OnActivated lifecycle event in CM that is related to OnNavigatedTo, but we want the above to be baked in so we don’t have to do it in every page code behind
If you’re not using Reactive Extensions (i.e. Observable.Start) then you’re doing it wrong.
Hi Arash,
Care to elaborate? Maybe share some code on how you would do the above with RX?
Hi, all you have to do is:
Observable.Start(SomeFunctionYouWantOffTheUiThread) // function is run on some thread from the ThreadPool
.ObserveOnDispatcher() // switches you back to UI thread to process results
.Subscribe(result => ProcessResult(result)) // happens on the UI thread so you can update the UI without a cross thread exception
[...] best time to do any heavy-lifting in your Windows Phone 7 apps. The best thing is to wait for the first call to LayoutUpdated after the page has completed navigation. Since then, I’ve also had a good read of Rob Eisenberg‘s simply jaw-dropping [...]