… when you’re in OutOfBrowser mode and you don’t yet have RootVisual set to something. Let me explain.
Early this week I was struggling with a Silverlight app that would work just fine when running IN-browser, but then when run OUT-of-browser (OOB) it would never show the initial content. After lots and lots of debugging and trial and error, I found that the first WCF service call was never returning (never calling it’s Completed event handler).
In the simplified code below, notice that we are calling a WCF service (asynchronously, as all service calls in Silverlight are done) and doing some follow-up work in the Completed handler, including setting the RootVisual.
private void Application_Startup( object sender, StartupEventArgs e ) { SomeServiceClient svc = new SomeServiceClient(); svc.AddCompleted += delegate( object sender2, AddCompletedEventArgs e2 ) { MessageBox.Show( e2.Result.ToString() ); RootVisual = new MainPage(); }; svc.DoSomeWork( 2, 3 ); }
In this case, when running OOB, the service will never return, and therefore never call the completed event. In fact, I think it never actually makes the outbound call. I had breakpoints over in the service implementation that would not get hit. No exception, nothing. Not even break on all exceptions would show anything.
The only thing I can come up with is that it has something to do with dispatching messages through the message pump to get the WCF call working. When there is no RootVisual, there is no UI (no dispatcher) to help with that. When running IN-browser, we must be leaning on the browser UI thread that’s already pumping messages.
So the fix is as simple as making sure RootVisual is set to something before the first WCF call. We have a case where we don’t know what content to show until we get back from the first service call, so I show an empty Panel, and then add the content in the service Completed handler.
private void Application_Startup( object sender, StartupEventArgs e ) { RootVisual = new Grid(); SomeServiceClient svc = new SomeServiceClient(); svc.AddCompleted += delegate( object sender2, AddCompletedEventArgs e2 ) { MessageBox.Show( e2.Result.ToString() ); var panel = RootVisual as Panel; panel.Children.Add( new MainPage() ); }; svc.DoSomeWork( 2, 3 ); }