This is a migrated thread and some comments may be shown as answers.

Change Tabs creates Unstable Map Providers. (Memory Leak)

3 Answers 20 Views
Map
This is a migrated thread and some comments may be shown as answers.
Don
Top achievements
Rank 1
Don asked on 13 Sep 2018, 06:04 PM

I am finding:
1) Create a PAGE, and VIEW MODEL
2) ON the Page:
Add a Tab Control with TWO Tab Items, on each Tab Item add a RadMap and a ComboBox
3) In the VM Create an Observable Collection of Providers and assign to both Combo Boxes on each Tab Item.
4) In the VM create a property(INotifyPropertyChanged) for each SELECTED Provider from each ComboBox, and BIND the Provider to each Map's Provider Dependency Property. (One List / Two Selected Items /Two Maps)
5) Run the App, switch between the Tabs and switch between the ComboBox's Selected Provider and you get botched providers displaying mixed data.
I have determined that when tabbing from one TabItem to an other, the RadMap gets Unloaded and then Reloaded each time, and several resources gets messed up because you do not call the DISPOSE. But, in fact you cant or else you would not be able to tab back... so there are several additional week references that are not detached and memory will continue to leak leading to poorly managed provider tiles etc...  Either that, or there are static references in both Maps reference... That I am not sure yet, still investigating and leaning on the Provider itself.

Has anyone else seen bad behavior on the RadMap with multiple Providers Binding on several Tabs?

thanks,

Don

 

3 Answers, 1 is accepted

Sort by
0
Petar Mladenov
Telerik team
answered on 18 Sep 2018, 07:27 AM
Hi Don,

Generally a single RadMap provider is not designed for simultaneous usage in multiple RadMap instances. We reproduced the issues you described (and some exceptions) with simple setup with no viewmodels:
this.combo1.ItemsSource = this.combo2.ItemsSource = new ObservableCollection<MapProviderBase>()
           {
               new OpenStreetMapProvider(),
               new ArcGisMapProvider() { Mode = ArcGisMapMode.Terrain },
           };
2 RadMap Instances in 2 TabItems have their Provider property bound to the SelectedValue of the corresponding ComboBox. Issues start when both maps have the same provider.
RadMap and Map providers are IDisposable but we do not call the dispose method in the Unloaded event of the Map. This is a WPF framework responsibility (calling Dispose) and generally unloading a control doesn't mean no other controls or classes have live reference to the unloaded control. To dispose map or the providers you can call the Dispose function manually. For example in this scenario, we successfully solved the issues with Unloaded event handler and the Dispose code (which is part of the Map's Dispose):

private void RadMap_Unloaded(object sender, RoutedEventArgs e)
       {
           RadMap map = sender as RadMap;
           if (map != null)
           {
               foreach (object item in map.Providers)
               {
                   IDisposable provider = item as IDisposable;
                   if (provider != null)
                   {
                       provider.Dispose();
                   }
               }
               map.Providers.RemoveAll();
           }
       }

When maps are reloaded , however, you need to assign the selected provider again. That is why we basically encourage you to use separate models and separate providers for separate views:
this.combo1.ItemsSource = new ObservableCollection<MapProviderBase>()
            {
                new OpenStreetMapProvider(),
                new ArcGisMapProvider() { Mode = ArcGisMapMode.Terrain },
            };
 
            this.combo2.ItemsSource = new ObservableCollection<MapProviderBase>()
            {
                new OpenStreetMapProvider(),
                new ArcGisMapProvider() { Mode = ArcGisMapMode.Terrain },
            };


Regards,
Petar Mladenov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
0
Don
Top achievements
Rank 1
answered on 18 Sep 2018, 10:55 AM

Can you explain it in MVVM terms? this is code behind.

I m using MVVM, once you dispose of the Providers in code behind, you have lost BINDING of the provider.

How do you support MVVM?

Thanks,

Don

0
Petar Mladenov
Telerik team
answered on 20 Sep 2018, 11:18 AM
Hi Don,

Yes, with the dispose approach binding is lost in order to improve the memory and the single instance of provider being used by multiple map instances. Please consider such scenarios as not supported in RadMap - multiple maps using single provider. To preserve MVVM pattern, I encourage you to use the second approach with separate models for the separate comboxes:

this.combo1.ItemsSource = new ObservableCollection<MapProviderBase>()
            {
                new OpenStreetMapProvider(),
                new ArcGisMapProvider() { Mode = ArcGisMapMode.Terrain },
            };
 
            this.combo2.ItemsSource = new ObservableCollection<MapProviderBase>()
            {
                new OpenStreetMapProvider(),
                new ArcGisMapProvider() { Mode = ArcGisMapMode.Terrain },
            };


Regards,
Petar Mladenov
Progress Telerik
Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Tags
Map
Asked by
Don
Top achievements
Rank 1
Answers by
Petar Mladenov
Telerik team
Don
Top achievements
Rank 1
Share this question
or