Null Ref. Exception on load

May 26, 2009 at 5:23 PM

In my application I'm using the VE control in a dialog where I can pass misc. data to it and the dialog will take care of mapping out that data. I have several hooks to this throughout my app, but the problem I'm having is that the map only loads the first time I open the dialog. If I close the dialog and open it a second time, I get this exception:

Exception of Type "System.NullReferenceException"

Message: Object reference not set to an instance of an object.

Source: InfoStrat.VE

Data:

StackTrace:
   at InfoStrat.VE.VEMap.VEMap_Loaded(Object sender, RoutedEventArgs e)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
   at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
   at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
   at MS.Internal.LoadedOrUnloadedOperation.DoWork()
   at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
   at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
   at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
   at System.Windows.Interop.HwndTarget.OnResize()
   at System.Windows.Interop.HwndTarget.HandleMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
   at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)

 

The specific line this is happening on is:

this.globeControl.Host.RenderEngine.Initialized += new EventHandler(RenderEngine_Initialized);

where the RenderEngine property is null.

Any ideas why this works fine the first time a map control is used but it's null after that?

Coordinator
May 26, 2009 at 6:08 PM

Perhaps... The control does create a hidden window to host the raw control (mainly just to get the rendering context, but it has to exist.)  When you close the dialog the control may get destroyed and that window as well.

I never tested a situation like this, so it is possible that the initialization is not perfectly symmetric the second time.  Also there could be a timing issue where the second time it ends up going through the intialization quicker or a different order, and the VE control isn't ready yet.

I'd recommend trying to either hide and show your dialog rather than destroy it, or maintain a reference to a single copy of the VEMap control and add and remove and re-add the single control to your dialog each time.

May 27, 2009 at 10:58 PM

I tried your suggestion of keeping a single VEMap control and inserting it into the dialog whenever I load it. That got around the first problem I was having, but introduced another one.

System.InvalidOperationException was unhandled by user code
  Message="Operation is not valid due to the current state of the object."
  Source="Microsoft.MapPoint.Rendering3D"
  StackTrace:
       at Microsoft.MapPoint.Rendering3D.RenderThread.InitializeRender()
       at Microsoft.MapPoint.Rendering3D.RenderEngine.ManuallyInitializeRender()
       at InfoStrat.VE.PublicEventsGlobeControl.InitRenderEngine()
       at InfoStrat.VE.VEMap.VEMap_Loaded(Object sender, RoutedEventArgs e)
       at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
       at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
       at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
       at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
       at System.Windows.BroadcastEventHelper.BroadcastEvent(DependencyObject root, RoutedEvent routedEvent)
       at System.Windows.BroadcastEventHelper.BroadcastLoadedEvent(Object root)
       at MS.Internal.LoadedOrUnloadedOperation.DoWork()
       at System.Windows.Media.MediaContext.FireLoadedPendingCallbacks()
       at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
       at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget)
       at System.Windows.Media.MediaContext.Resize(ICompositionTarget resizedCompositionTarget)
       at System.Windows.Interop.HwndTarget.OnResize()
       at System.Windows.Interop.HwndTarget.HandleMessage(Int32 msg, IntPtr wparam, IntPtr lparam)
       at System.Windows.Interop.HwndSource.HwndTargetFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
       at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter)
       at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler)
  InnerException:

Coordinator
May 27, 2009 at 11:14 PM

Does that occur the first time or only after the second time you show the dialog?

The error message there indicates that Virtual Earth isn't initialized properly when that call happens.  It could still be losing some references or something depending upon how you are adding and removing the control.

Did you try just hiding and showing the dialog box instead?

May 28, 2009 at 4:40 PM

It still loads correctly the first time, but the second time is when the error happens.

I'm gonna experiment with hiding and showing the dialog box, but that really isn't an ideal solution for what I need.

May 28, 2009 at 5:43 PM

So the show/hide idea does get around the problem of these exceptions, however it massively bloats the amount of memory the app uses (by about 250 megs). I suppose that *might* be acceptable if the sole purpose of the application was working with the map, but for an enterprise-scale business application it just isn't feasible.

Coordinator
May 28, 2009 at 5:58 PM

Well that at least narrows down the possible causes to this control.

Why does keeping the dialog box bloat by 250 megs?  You were otherwise creating and destroying the dialog box anyway.

Unfortunately, I don't have time to track down this bug right now.  (Billable projects have priority.)  If this is critical to your project and you have some funding, contact me privately and we could fast track this.  Otherwise I won't be able to address it when I next have downtime, which won't be until at least for a month or two.

You're free to edit the source of course if you find the problem.  I'll incorporate your fix into the control if you want.