473,657 Members | 2,693 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Is this really an Illegal Cross Thread Call?

I have a Thread making a callback to a Form function that alters Form data.
Of course, the debugger is telling me, "Cross-thread operation not valid:
Control 'FormTest' accessed from a thread other than the thread it was
created on."

But I am locking before I touch the shared data, so do I actually need to
worry about this, or is it just the debugger being oversimplistic?

Specifically, I have:

public delegate void TestEvent(ref string Payload);

public class FormTest : System.Windows. Forms.Form
{
...
void Run
{
TestHarness test = new TestHarness();
test.Callback += TestFunction; // Callback is of type
TestEvent
Thread t = new Thread(new ThreadStart(tes t.Go));
t.IsBackground = true;
t.Start();
}

private void TestFunction(re f string Payload)
{
lock(this) WriteOut(ref Payload); // ??? Doesn't this lock
prevent thread synchronization problems???
}

private void WriteOut(ref string Payload)
{
this.Text = Payload;
}
Apr 21 '06 #1
18 6584
Dave,
But I am locking before I touch the shared data, so do I actually need to
worry about this, or is it just the debugger being oversimplistic?


Yes the warning is right. You should only access Winforms controls
from the thread they were created on. Lock doesn't help here.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Apr 21 '06 #2
Hi,
Thank you for posting.
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
InvalidOperatio nException with the message, "Control control name accessed
from a thread other than the thread it was created on."

To make the access to your controls in a thread-safe way, you should use
the Invoke method of the control. The following is a sample.

delegate void WriteOutDelegat e(ref string Payload);
void test_Callback(r ef string Payload)
{
object[] args = new object[1]{Payload};
this.Invoke(new WriteOutDelegat e(WriteOut),arg s);
}

private void WriteOut(ref string Payload)
{
this.Text = Payload;
}

Hope this will help you.
If you have any other concerns, or need anything else, please don't
hesitate to let me know.
Sincerely,
Linda Liu
Microsoft Online Community Support

=============== =============== =============== =======
When responding to posts,please "Reply to Group" via
your newsreader so that others may learn and benefit
from your issue.
=============== =============== =============== =======

Apr 21 '06 #3
Dave Booker wrote:
I have a Thread making a callback to a Form function that alters Form data.
Of course, the debugger is telling me, "Cross-thread operation not valid:
Control 'FormTest' accessed from a thread other than the thread it was
created on."

But I am locking before I touch the shared data, so do I actually need to
worry about this, or is it just the debugger being oversimplistic?


Yes, you need to worry about it. UI components have thread affinity -
they really, really shouldn't be touched except on their own thread.
(Aside from the calls to CreateGraphics, InvokeRequired, BeginInvoke
and Invoke.)

One further note - you appear to be passing string references by
reference without using the by-ref semantics. Is there a reason for
this? You may be unaware of how parameter passing works. See
http://www.pobox.com/~skeet/csharp/parameters.html

Jon

Apr 21 '06 #4
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Linda Liu [MSFT] wrote:
delegate void WriteOutDelegat e(ref string Payload);
void test_Callback(r ef string Payload)
{
object[] args = new object[1]{Payload};
this.Invoke(new WriteOutDelegat e(WriteOut),arg s);
}
That also, rather usefuly, helped me resolve getting my head around
the SerialPinChange dEventHandler and using Invoke() when you need to
modify Form UI elements.

So thanks from me for coincidental assistance :)
Sincerely,
Linda Liu
Microsoft Online Community Support


- --
Chris Crowther
Developer
J&M Crowther Ltd.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.1 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFESJh8z8b l0gyT/hERAswcAKCQJ53B UPhJL1GCFd5qfkF F6b9ZBgCeO3nN
mkl2xlQQsE/9WnHUsRJr+gA=
=22sA
-----END PGP SIGNATURE-----

Apr 21 '06 #5
So I obviously don't understand something important about locking. It looks
to me like the only way the other thread can touch the Form control is
through the TestFunction, and the TestFunction locks the entire object until
the Form text is changed. How could this possibly go wrong?

And would your answer be different if I make either TestFunction() or
WriteOut() static?
"Mattias Sjögren" wrote:
Dave,
But I am locking before I touch the shared data, so do I actually need to
worry about this, or is it just the debugger being oversimplistic?


Yes the warning is right. You should only access Winforms controls
from the thread they were created on. Lock doesn't help here.
Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.

Apr 21 '06 #6
Thank you for this response. But I am obviously failing to understand what's
going on behind the scenes:

"Linda Liu [MSFT]" wrote:
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.
Given that my private WriteOut() method is only called in a locked
condition, and (let us assume) is guaranteed to return, could you give an
example of any unsafe multi-threading effects that could be achieved on this
class?

To make the access to your controls in a thread-safe way, you should use
the Invoke method of the control. The following is a sample.

delegate void WriteOutDelegat e(ref string Payload);
void test_Callback(r ef string Payload)
{
object[] args = new object[1]{Payload};
this.Invoke(new WriteOutDelegat e(WriteOut),arg s);
}

private void WriteOut(ref string Payload)
{
this.Text = Payload;
}


I thought Invoke is just a means of reflection. What is it about this
construct that ensures thread safety?

To me it just looks like a hideous kludge ... and I can't even understand
how it could help.
Apr 21 '06 #7
Uh oh ... it must be worse than I thought. I migrated from C++ to C# over a
year ago, and I thought I had this straight, but I don't understand what
you're saying even afer rereading your parameters.html page.

Just to be clear, in my example, every function call in the callback loop
uses "ref string" arguments. In this case I am not modifying the string
values and so the only reason to do this, I thought, was performance -- to
avoid making copies of very large strings. Thinking about it further I
suppose that since strings are immutable reference types, then they are
passed by reference anyway and I wouldn't incur any performance penalty
unless I tried to modify them, in which case a new string would be created
and I would just be causing the original string to be replaced by it.

Is this what you were referring to when you say I am "passing string
references by
reference without using the by-ref semantics," or am I committing an actual
mistake of some sort in this example?
"Jon Skeet [C# MVP]" wrote:
One further note - you appear to be passing string references by
reference without using the by-ref semantics. Is there a reason for
this? You may be unaware of how parameter passing works. See
http://www.pobox.com/~skeet/csharp/parameters.html


Apr 21 '06 #8
Taking out a lock on the form is completely irrelevant to thread-affinity.
It isn't the debugger being over-simplistic: rather, the runtime (correctly)
catching your incorrect usage. What you are trying to do will not work, so
stop trying to do it. You *need* to .Invoke() or .BeginInvoke() back to the
owning thread before you update the UI. Linda's response seems pretty
comprehensive, else read MSDN / google.

And for reference, lock(this) is often a bad idea, as it allows objects code
of your scope to *without realising it* share a lock with you; a better
approach is to lock on a dedicated handy object, which you may (or may not)
choose to publicly expose for other callers to sync against; at least if
they lock(something. SyncLock) then they expect you to be using that lock
too.

Marc

Apr 21 '06 #9
Typo:
as it allows objects code of your scope should beas it allows objects out of you scope


i.e. external code may want to sync itself using your object as the lock (no
technical reason why it shouldn't)

Marc
Apr 21 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
1888
by: rob | last post by:
Dear All, I am getting an error "Illegal cross-thread operation". I am not creating any threads. I know internally there are many threads running, though. Does that mean that no form can call a function from another form even if there is a parent-child relationship? Aren't controls like TreeView based on forms. If so then why can a form containing a TreeView call members of the TreeView? If you're interested here is my scenario:
12
2369
by: [Yosi] | last post by:
What I should do to return back the permissin I had in VS2003 , that allowd me to access public methode of one Class from other Thread. I have Class A(FORM) which create new thread (new class B), the new class thread get as parameter reference to his father( CLASS who mad it (classA)), The new thread need to call methodes from his father like myfathe.methode(), This worked in VS 2003 but now in VS 2005 Beta throw an exception : An...
4
4418
by: oran johnson | last post by:
Illegal cross-thread operation: Control 'PopupInfo' accessed from a thread other than the thread it was created on. Can I track this down using the debugger? Thanks.
12
7187
by: Wilfried Mestdagh | last post by:
Hi, Using P/Invoke I use PostMessage to send a message from one thread to another. I'm pretty sure this has already worked in dotnet. but I've upgraded version 2 few day ago. Now I have an illegal cross thread operation if posting a message. Is this a bug introduced in latest version of dotnet ? It is very legal to use postmessage because the message will execute in context of the thread the one was posted to. Same with...
0
8403
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8316
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8833
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8737
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8610
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
7345
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
4168
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
2735
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1967
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.