ThinkGeo.com    |     Documentation    |     Premium Support

Changing layer style while the layer is still refreshing

Hi,
  I’m working on doing some InMemoryLayer thematic maps using a custom style with the ValueStyle.  We’re trying to render about 70k points on the map and it can take a few seconds.  We’re using the MultipleTile TyleType and can see each of the tiles drawing which is good because it indicates progress to the user.


We’re using MapSuite WPF (tried 7 & 8) in a hosted container in WinForms 




Where we’re having a problem is when we try to change ValueStyle before the layer has finished refreshing (something the selected color range isn’t looking so good so you might want to pick a different one without waiting a few seconds for the refresh to complete).  We almost always get this error within 2-3 attempts:



I’m probably missing something pretty fundamental here - only been using MapSuite a few weeks and had been making good progress until this


An unhandled exception of type ‘System.InvalidOperationException’ occurred in WpfDesktopEdition.dll
 
Additional information: Collection was modified; enumeration operation may not execute.
 
 
System.InvalidOperationException was unhandled
  HResult=-2146233079
  Message=Collection was modified; enumeration operation may not execute.
  Source=WpfDesktopEdition
  StackTrace:
       at ThinkGeo.MapSuite.WpfDesktopEdition.Tile.<>c__DisplayClass6.<DrawException>b__4()
       at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
       at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
       at System.Windows.Threading.DispatcherOperation.InvokeImpl()
       at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
       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 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 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, 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.Threading.Dispatcher.Run()
       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 WpfApplication1.Application.Main() in D:\Projects\SpatialestX\MapSuite-Playground\WpfApplication1\obj\x86\Debug\Application.g.vb:line 65
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       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 System.Threading.ThreadHelper.ThreadStart()
  InnerException: 






Hi Mark,



It’s our pleasure to assist you.

From the exception stack, I think I can image this error as during the map refreshing, it is under multi-thread. I think you can try the below ways:

1) Locking the InMemoryLayer when you trying to change its style. 

2) Switch the multi-thread to single thread by changing the LayerOverlay TileType which contains the InMemoryLayer from multiTile To SingleType.



Hope it helps and if the issue persists, please feel free to let us know.

Thanks,

Troy

Thanks for that.  SingleTile method work. I eventually went for SyncLock on the feature layer and this seems to have done the trick.  Thanks for your help.

Hi Mark, 
  
 Good to hear it helps and hope you will have a good journey on map suite. 
 Thanks, 
 Troy