|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Invoke or BeginInvoke cannot be called on a control until the window handle has been created.A first chance exception of type 'System.InvalidOperationException' occurred in System.Windows.Forms.dll Additional information: Invoke or BeginInvoke cannot be called on a control until the window handle has been created. However, I already called CreateControl on the Control in question: ThreadSync.invoker = new Form(); ThreadSync.invoker.CreateControl(); What can I do to make this work properly? I don't want to make the Control visible, but it seems that no window is created unless the control is made visible. Is there another method besides Control.Invoke that I can use to run an eventhandler to my main thread? Hi Ben,
You're right that when when a window is not visible when it is ceated, the window's IsHandleCreated property returns false. In this case, we couldn't call the Invoke or BeginInvoke method on the window. Only when a thread which is other than the thread the window is created on, is attempting to access the window, an InvalidOperationException occurs. And at this time, we should call the Invoke or BeginInvoke method of the window to execute a delegate on the thread that owns the window's underlying window handle. In fact, if the thread other than the thread the window is created on is not attempting to access the window itself or any UI elements on the window, we needn't use the Invoke or BeginInvoke method of the window. > Is there another method besides Control.Invoke that I can use to run an eventhandler to my main thread?Could you call the event handler in your main thread directly? Hope this helps. If you have any question, please feel free to let me know. Sincerely, Linda Liu Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights.
Show quote
"Linda Liu [MSFT]" <v-l***@online.microsoft.com> wrote in message What if the thread (not the main thread) wants to run code on the UI thread?news:T57qu17XHHA.1136@TK2MSFTNGHUB02.phx.gbl... > Hi Ben, > > You're right that when when a window is not visible when it is ceated, the > window's IsHandleCreated property returns false. In this case, we couldn't > call the Invoke or BeginInvoke method on the window. > > Only when a thread which is other than the thread the window is created > on, > is attempting to access the window, an InvalidOperationException occurs. > And at this time, we should call the Invoke or BeginInvoke method of the > window to execute a delegate on the thread that owns the window's > underlying window handle. > > In fact, if the thread other than the thread the window is created on is > not attempting to access the window itself or any UI elements on the > window, we needn't use the Invoke or BeginInvoke method of the window. > To do that, I first have to run code on the main thread... polling isn't >> Is there another method besides Control.Invoke that I can use to run an > eventhandler to my main thread? > > Could you call the event handler in your main thread directly? pretty, the .NET UI message loop doesn't use MsgWaitForMultipleObjectsEx so I can't use events, etc. I could use SendMessage, but then I lose all the type-safety of .NET. Control.Invoke seems to be the new and approved way of making a method call in the context of another thread, and with Mehdi's helpful instruction to call the Handle property's getter, it's now working. To elaborate on what I'm trying to do, this is a medical sensor system, and data collection occurs on long-lived worker threads (mostly just a single worker thread, but some devices have threaded code in the vendor libraries). The data collection threads are higher priority, so they aren't impacted by processing bursts. I need to synchronize all the data back on the main thread to be processed and logged. We can load plugins to display data graphically, but none of these is guaranteed to be loaded, so their windows are unsuitable for use with Control.Invoke. Hence my desire for an invisible window, created at the very beginning of the program, which enables executing event handlers on the main thread. Actually, most of the data collection code (USB serial port interface) is done in C++/CLI using a lockless queue to pass commands to the I/O thread and SetEvent to wake it, and PostMessage to return data buffers to the main thread. However, this particular vendor device is USB with a custom driver, and has no non-blocking API, so I have to dedicate a thread to waiting for data to arrive, and then pass the data back to the main thread, and Control.Invoke seemed just the ticket to do this safely. There's no need to drop into C++, since this device can't be reconfigured, it just sends a relatively high-rate data stream. Hi Ben,
Thank you for your prompt response and detailed explanation. I agree with you that Control.Invoke is a safe way to make a method call in the context of another thread. If there is only one thread calling a method in the context of another thread, and the called method has no statement to access any UI element, this thread could call the method directly, without using Control.Invoke. However, if there're several threads that are attempting to call the method at the same time, thread conflict may occurs. In this case, using Control.Invoke is a better choice. Mehdi's solution seems great. I use Reflector to see the source code in the Control.Handle property. I did see that a handle is to be created if it has not created, in the Handle property getter. Hope this helps. If you have any other question, please feel free to let me know. Sincerely, Linda Liu Microsoft Online Community Support On Mon, 5 Mar 2007 15:35:56 -0600, Ben Voigt wrote:
> What can I do to make this work properly? I don't want to make the Control You can force the Handle creation without showing the window by simply> visible, but it seems that no window is created unless the control is made > visible. Is there another method besides Control.Invoke that I can use to > run an eventhandler to my main thread? accessing it: Form1 form = new Form1(); IntPtr handle = form.Handle; // Forces creation of the handle // Now you can call Invoke or BeginInvoke on your form It is very important that you force creation of the window handle in the UI thread.
Show quote
"Mehdi" <vio***@REMOVEME.gmail.com> wrote in message That's working much better than CreateControl(). Thanks very much.news:1izwplqjdrt12.1wsog6n8bsd8n.dlg@40tude.net... > On Mon, 5 Mar 2007 15:35:56 -0600, Ben Voigt wrote: > >> What can I do to make this work properly? I don't want to make the >> Control >> visible, but it seems that no window is created unless the control is >> made >> visible. Is there another method besides Control.Invoke that I can use >> to >> run an eventhandler to my main thread? > > You can force the Handle creation without showing the window by simply > accessing it: > > Form1 form = new Form1(); > IntPtr handle = form.Handle; // Forces creation of the handle > // Now you can call Invoke or BeginInvoke on your form > I know :)> It is very important that you force creation of the window handle in the > UI > thread. |
|||||||||||||||||||||||