Cross-thread operation not valid when retrieving form handle

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I have an application where the following bit of code throws the
"Cross-thread operation not valid" error every once in a while:

(class is called "WindowPositioner")
Public Shared Function GetConcentricLocation(ByVal parentForm As Form, ByVal
childForm As Form) As Point

Dim ScreenRect As Rectangle
Dim sc As Screen
Dim ph As System.IntPtr

ph = parentForm.Handle ' Error occurs here (sometimes!)
sc = Screen.FromHandle(ph)
ScreenRect = sc.WorkingArea()
 
Hi Luetz,

From the exception "Cross-thread operation not valid" that your application
throws, it seems that a thread in your application is attempting to access
a control that is created on another thread.

FYI, If you use multithreading to improve the performance your Windows
Forms applications, you must be careful to make calls to your controls in a
thread-safe way. Access to Windows Forms controls is not inherently thread
safe. If you have two or more threads manipulating the state of a control,
it is possible to force the control into an inconsistent state. Other
thread-related bugs are possible as well, including race conditions and
deadlocks. It is important to ensure that access to your controls is done
in a thread-safe way.

The .NET Framework helps you detect when you are accessing your controls in
a manner that is not thread safe. When you are running your application in
the debugger, and a thread other than the one which created a control
attempts to call that control, the debugger raises an
InvalidOperationException with the message, "Control control name accessed
from a thread other than the thread it was created on."

To solve this problem, we should use a delegate to point to the method that
accesses the control and then call the Invoke method of the control to
execute the delegate on the thread that the control's underlying handle was
created on.

For more information on how to make thread-safe calls to Windows Forms
controls, you may visit the following link.

http://msdn2.microsoft.com/en-us/library/ms171728.aspx

Please check your program to see where you have used multiple thread (e.g.
you create a new thread somewhere to execute some method) and then solve
the problem using the above approach. If you need our further assistance,
please send me your sample project that could just reproduce the problem.
To get my actual email address, remove 'online' from my displayed email
address.
I can see that System.Windows.Forms.Control.get_Handle() is getting called
shortly after I enter the GetConcentricLocation code, which makes sense, but
I don't know what all that other code that is executing is for.

All the other code is called internally.

Hope this helps.
If you have anything unclear, 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.
 
Hi Luetz,

How about the problem now?

If the problem is not resolved or you need our further assistance, please
feel free to let me know.

Thank you for using our MSDN Managed Newsgroup Support Service!


Sincerely,
Linda Liu
Microsoft Online Community Support
 
I looked into the body of information on cross-thread calls but could not
determine a good way to retieve a form's Handle in a generic way; one not
specific to given form.

I did however rewrite the function as seen below and the error has not
reoccurred.

Public Shared Function GetConcentricLocation(ByVal parentForm As Form, ByVal
childForm As Form) As Point
Dim ScreenRect As Rectangle
ScreenRect = Screen.GetWorkingArea(parentForm)
Dim pt As Point
pt.X = ((parentForm.Left + parentForm.Right) - childForm.Width) / 2
If pt.X < ScreenRect.X Then
pt.X = ScreenRect.X
ElseIf (pt.X + childForm.Width) > (ScreenRect.X + ScreenRect.Width) Then
pt.X = (ScreenRect.X + ScreenRect.Width) - childForm.Width
End If
pt.Y = ((parentForm.Top + parentForm.Bottom) - childForm.Height) / 2
If pt.Y < ScreenRect.Y Then
pt.Y = ScreenRect.Y
ElseIf (pt.Y + childForm.Height) > (ScreenRect.Y + ScreenRect.Height) Then
pt.Y = (ScreenRect.Y + ScreenRect.Height) - childForm.Height
End If
Return pt
End Function

Thank you for the assistance.
Tom
 
Hi Tom,

Thank you for your reply.
I looked into the body of information on cross-thread calls but could not
determine a good way to retieve a form's Handle in a generic way; one not
specific to given form.

To retrieve a form's Handle, you could use the Handle property of the form.
I think it is a generic way because Handle is a property of Control class.
Could you please tell me what you mean in the above sentence?

By the way, your modified function seems good, which uses the
Screen.GetWorkingArea method to get the screen's rectangle. Then you
needn't retrieve the parent form's handle any longer.

I look forward to your reply.


Sincerely,
Linda Liu
Microsoft Online Community Support
 
Back
Top