ThinkGeo.com    |     Documentation    |     Premium Support

"Invoke or BeginInvoke cannot be called on a control until the window handle has been created."

I'm having several issues with the Release candidate version of the software. I believe that most of them are related to threading problems. The most recent one is that a few seconds after I close my map, I get the error in the subject. I'm not doing anything special with the threading. I put read locks and write locks around my code everywhere that I'm looking at stuff, but I haven't specifically turned on or off threading. I believe it's on by default, but so far it's only causing me grief.


The stack trace on the error after I close my map is the following:

"   at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)\r\n   at System.Windows.Forms.Control.BeginInvoke(Delegate method, Object[] args)\r\n   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x5e1f8125aa040824(Object x2680f14bfcc5c488)\r\n   at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)\r\n   at System.Threading.ExecutionContext.runTryCode(Object userData)\r\n   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)\r\n   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)\r\n   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)"


I'm happy to try any ideas you can give me.


Kimberly



I have been playing around with the MapThreadingMode. If I set it to SingleThreaded, this problem goes away. If I set it to MultiThreaded, the issue is definitely present.



Kimberly,


Thanks for your post!
 
Firs of all, I want to make sure the exception message is “Invoke or BeginInvoke cannot be called on a control until the window handle has been created”?  I cannot get it from the exception stack track.
 
Second, I want to make sure you did use any other threads in your application? How do you create your WinformMap control instance for the application, it is created in another thread instead of Main thread? Could you please supply some sample or codes to recreate the exception?
 
Third, if you are interested, we can explain how and why we think this problem should not happen in our Map control.
For simple application as below, if I close the form when the working thread is still running, the exception as you described will happen:

Thread workerThread = new Thread(new ParameterizedThreadStart(ChangeFormName));
workerThread.Start();

private void ChangeFormName(object parameterObject)
{
   Thread.Sleep(5000);
   ChangeText changeText = new ChangeText(ChangeFormText);
   this.BeginInvoke(changeText);
}

But if I set the workerThread to background thread like this: 



workerThread.IsBackground = true;

This exception will be disappeared. That’s because the workerThread will be terminated once you close your application form.  You know, all the working threads for drawing used in WinformsMap control are background thread, so this exception should not happen at all ideally. So we are very curious why the exception happened in your app.


Let me know if you have more problems.
Thanks.
 
Sun

I’ll post the stack trace and exception again, just to be sure it was the right one. (These were both just copied right out of the view detail window on the exception.) 
  
 Exception: {“Invoke or BeginInvoke cannot be called on a control until the window handle has been created.”} 
  
 StackTrace: 
 "   at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)\r\n   at System.Windows.Forms.Control.BeginInvoke(Delegate method, Object[] args)\r\n   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x27d0591c2adda8d9(RectangleShape xb35a33b423b17f65, Overlay x99251f66cdabc2ad, Int32 xa209325f5c895f7e, Int32 x7454a0d1965919b1, GeographyUnit xbb704b4400ce6f76)\r\n   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x27d0591c2adda8d9(Object x9c95f4613bdc3113)\r\n   at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)\r\n   at System.Threading.ExecutionContext.runTryCode(Object userData)\r\n   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)\r\n   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)\r\n   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)" 
  
  
 I’m not using any other threads in my application, I already told you that. I also said that if I turn off MultiThreading on your control, this issue goes away.  
  
 This issue comes up after I have closed the window with the map on it only when I have the Map in default/MultiThreaded mode. The issue gets raised sometime after the map form is closed. The form with the map is in an MDI application, so it’s only up part of the time. If I close the map form and the rest of the application is still running, this happens, but not every time.  
  
 What I think is happening is that the map is still trying to redraw (I have another post about slow SQL performance) when I close the map form. The redrawing is happening on another thread (not mine, but built into the control) and then it tries to access the control which was likely GC’d already. I have double and triple checked that I have read locks and write locks around every place I need them, but I could always have missed something. At the same time, basically all the map is doing is loading up several layers, sometimes panning, sometimes not, and then being closed. Most of the layers are SQL layers, there are a couple of InMemoryFeatureLayers, and I’m using a GoogleOverlay. Sometimes the InMemoryFeatureLayers have features on them and sometimes they don’t.  
  
 Any ideas? 
 Kim

Hi Kim,


I made a sample with all kinds of Layers as you mentioned (2 MsSql2008FeatureLayers, 1 Google Layer, 2 InMemoryLayers), unfortunately I still failed to reproduce the invoke exception as the top of the post.
 
You can get sample application is in the attachment and play around with it to see if this problem will happen on your machine.
 
Sorry for the inconvenience, any more questions please let me know.
 
Thanks,
 
Sun 

915-Post5988Demo.zip (33.5 KB)

I hadn't seen this recently, so I thought it had gone away with the latest version, but just now it came up again. (I think I said this before, but I'm guessing the map is still refreshing when I close the window. Given the performance issues I'm running into, this might just be a side effect of that. I am in the default threading mode.)


Here is the stack trace:


"   at System.Windows.Forms.Control.MarshaledInvoke(Control caller, Delegate method, Object[] args, Boolean synchronous)\r\n   at System.Windows.Forms.Control.BeginInvoke(Delegate method, Object[] args)\r\n   at ThinkGeo.MapSuite.DesktopEdition.WinformsMap.x5e1f8125aa040824(Object x2680f14bfcc5c488)\r\n   at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)\r\n   at System.Threading.ExecutionContext.runTryCode(Object userData)\r\n   at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)\r\n   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)\r\n   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)\r\n   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)"


Thanks!


Kimberly



Kimberly,


I tried to use a Timer to refresh the map every 500 milliseconds, then close the Form suddenly, but unfortunately, the exception never be raised.
 
I also attachment my sample to this post, you can take a look.
 
Sorry for the inconvenience!
 
Thanks, 
 
Sun 

970-Post5988Demo.zip (10.9 KB)