ThinkGeo.com    |     Documentation    |     Premium Support

Exception gets thrown even with DrawException set

Hi,

I noticed that if you use ThinkGeoCloudVectorMapsOverlay or ThinkGeoCloudRasterMapsOverlay as background map and configure DrawingExceptionMode to be DrawingExceptionMode.DrawException, even then it is possible that exceptions get thrown.

This can be easily tested with the Quick start example at https://gitlab.com/thinkgeo/public/thinkgeo-desktop-maps. I followed the instructions up to step 5 and then configured the DrawException mode:

private void mapView_Loaded(object sender, RoutedEventArgs e)
{
    // Set the Map Unit.
    mapView.MapUnit = GeographyUnit.Meter;

    // Add a base map overlay.
    var cloudVectorBaseMapOverlay = new ThinkGeoCloudVectorMapsOverlay("USlbIyO5uIMja2y0qoM21RRM6NBXUad4hjK3NBD6pD0~", "f6OJsvCDDzmccnevX55nL7nXpPDXXKANe5cN6czVjCH0s8jhpCH-2A~~", ThinkGeoCloudVectorMapsMapType.Light);
    cloudVectorBaseMapOverlay.DrawingExceptionMode = DrawingExceptionMode.DrawException;
    mapView.Overlays.Add(cloudVectorBaseMapOverlay);

    mapView.CurrentExtent = new RectangleShape(-20000000, 20000000, 20000000, -20000000);
}

If this application is started without network connectivity, the following exception is thrown:

	System.Net.WebException
	  HResult=0x80131509
	  Message=The remote name could not be resolved: 'cloud2.thinkgeo.com'
	  Source=System
	  StackTrace:
	   at System.Net.HttpWebRequest.GetRequestStream(TransportContext& context)
	   at System.Net.HttpWebRequest.GetRequestStream()
	   at ThinkGeo.Core.CloudMapClient.CreateWebRequest(String apiPath, String method, String parameters, String body, Int32 timeoutInSeconds, IWebProxy webProxy, Boolean isNeedToken)
	   at ThinkGeo.Core.CloudMapClient.xTY=()
	   at ThinkGeo.Core.CloudMapClient.Open()
	   at ThinkGeo.Core.ThinkGeoCloudVectorMapsLayer.OpenCore()
	   at ThinkGeo.Core.Layer.Open()
	   at ThinkGeo.Core.ThinkGeoCloudVectorMapsOverlay.DrawCore(RectangleShape targetExtent, OverlayRefreshType overlayRefreshType)
	   at ThinkGeo.Core.Overlay.Draw(RectangleShape targetExtent, OverlayRefreshType refreshType)
	   at ThinkGeo.Core.MapViewBase.b0o=(Overlay overlay, RectangleShape targetExtent, OverlayRefreshType refreshType)
	   at ThinkGeo.Core.MapViewBase.aUo=(IEnumerable`1 overlays, RectangleShape targetExtent, OverlayRefreshType refreshType)
	   at ThinkGeo.Core.MapViewBase.DrawCore(RectangleShape targetExtent, OverlayRefreshType overlayRefreshType)
	   at ThinkGeo.Core.MapViewBase.Y0o=(Object sender, EventArgs e)
	   at System.Windows.Threading.DispatcherTimer.FireTick(Object unused)
	   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
	   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
	   at System.Windows.Threading.DispatcherOperation.InvokeImpl()
	   at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
	   at MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(Object obj)
	   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
	   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
	   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
	   at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
	   at System.Windows.Threading.DispatcherOperation.Invoke()
	   at System.Windows.Threading.Dispatcher.ProcessQueue()
	   at System.Windows.Threading.Dispatcher.WndProcHook(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, Int32 numArgs)
	   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
	   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
	   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
	   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
	   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
	   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
	   at System.Windows.Application.RunDispatcher(Object ignore)
	   at System.Windows.Application.RunInternal(Window window)
	   at System.Windows.Application.Run(Window window)
	   at System.Windows.Application.Run()
	   at ThinkGeoWpfApp.App.Main()

Is this intended to work like this? I would have assumed that exception is thrown only if DrawingExceptionMode.ThrowException mode is used.

BR, Rasmus

Thanks,
Yes. The error happen when you open the layer. If you open the sample first. Then disconnect the internet and pan the map. You will find the exception won’t threw.

Thanks

Frank

Hi Frank,

Yes, I have noticed that. But why is the exception thrown instead of drawn on the map even if configured otherwise? I would expect the application to open and render possible exceptions to the map…

Because now the app can’t be started at all, if internet connection is down. I tried to catch any exceptions with the following code:

    private void mapView_Loaded(object sender, RoutedEventArgs e)
    {
        // Add a base map overlay.
        try
        {
            // Set the Map Unit.
            mapView.MapUnit = GeographyUnit.Meter;

            var cloudVectorBaseMapOverlay = new ThinkGeoCloudVectorMapsOverlay("USlbIyO5uIMja2y0qoM21RRM6NBXUad4hjK3NBD6pD0~", "f6OJsvCDDzmccnevX55nL7nXpPDXXKANe5cN6czVjCH0s8jhpCH-2A~~", ThinkGeoCloudVectorMapsMapType.Light);
            cloudVectorBaseMapOverlay.DrawingExceptionMode = DrawingExceptionMode.DrawException;
            mapView.Overlays.Add(cloudVectorBaseMapOverlay);
            mapView.CurrentExtent = new RectangleShape(-20000000, 20000000, 20000000, -20000000);
        }
        catch (Exception exception)
        {
            MessageBox.Show(exception.Message, "Exception", MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }

But the exception was not caught here, it was thrown somewhere outside the scope of the Loaded event handler…

BR, Rasmus

Thanks BR,
We are looking into more details. I think there is something we could do. Right now when we open the layeroverlay threw error. We may able to draw open exception to the tile too. It may need one or two days to implement this one. We will let you know once it available for you.

Thanks

Frank

1 Like

Hi Frank,

Great to hear that! Looking forward to getting the fix.

Thanks, Rasmus

Thanks BR,
We have fixed this one. You can try with the latest mapsuite 12 Beta version tomorrow(Nightly build process will push change to the NuGet every night).

The Test code would like this

   private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            // Set the map's unit of measurement to meters(Spherical Mercator)
            mapView.MapUnit = GeographyUnit.Meter;

            // Add Cloud Maps as a background overlay
            var thinkGeoCloudVectorMapsOverlay = new ThinkGeoCloudVectorMapsOverlay("itZGOI8oafZwmtxP-XGiMvfWJPPc-dX35DmESmLlQIU~", "bcaCzPpmOG6le2pUz5EAaEKYI-KSMny_WxEAe7gMNQgGeN9sqL12OA~~", ThinkGeoCloudVectorMapsMapType.Light);
            thinkGeoCloudVectorMapsOverlay.DrawingExceptionMode = DrawingExceptionMode.DrawException;
            mapView.Overlays.Add(thinkGeoCloudVectorMapsOverlay);

            // Set the map extent
            mapView.CurrentExtent = new RectangleShape(-10786436, 3918518, -10769429, 3906002);
        }

You will get result

One thing I need let you know even you set
thinkGeoCloudVectorMapsOverlay.DrawingExceptionMode = DrawingExceptionMode.ThrowException;
The main threading may not get notification and threw an error. Because the exception is in the C# task method it is not observed. You need turn the option on.
More details is here

Basically just copy
< runtime>
< ThrowUnobservedTaskExceptions enabled=“true”/>
< /runtime>

to you app.config.

Thanks

Frank

Hi Frank,

Thank you very much! I tested the new beta and it works like you described. This is now much better behavior as the application still runs under poor network coverage and when network is re-established, the map tiles start working again.

Thanks, Rasmus

Thanks Rasmus,
Good to know it works. We will push the change to the Prod release next week. Go ahead let us know if you have more questions.

Thanks

Franks

Hi Frank,

I noticed that the fix was made to ThinkGeoCloudVectorMapsOverlay, but if I change the example code to use ThinkGeoCloudRasterMapsOverlay, then the problem is still there… Can you also fix raster overlay to work the same way?

Thanks, Rasmus

Thanks Rasmus,
Yes. I have applied the changes to the ThinkGeoCloudRasterMapsOverlay as well as some others build-in overlay such as BingMapOverlay, OpenStreetMapOverlay etc. The nightly build process will push the changes to the NuGet. You can try with latest mapsuite V12 Beta.

Thanks

Frank

Hi Frank,

Thank you very much for the quick fix! It works now fine also with raster maps. Later we will also add support to other cloud services (Google maps, OpenStreetMap and general WMS services), so we’ll be able to test those after a few weeks.

Thanks, Rasmus

Thanks Rasmus,
Good to know it works. Go ahead let us know if you have any more questions.

Thanks

Frank