This question is related to the top rated comment of this question:
The STA model is used for COM objects that are not thread safe. That means they do not handle their own synchronization. A common use of this is a UI component. So if another thread needs to interact with the object (such as pushing a button in a form) then the message is marshalled onto the STA thread. The windows forms message pumping system is an example of this.
So the following example confuses me a bit..
Main is annotated with [STAThread]
.
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
I was supposing, that, since Form1 runs in a STAThread, every message to a UI-Component that is sent from another thread is marshalled onto the STA thread.
Therefore I expected, that a call like this would work:
public Form1()
{
InitializeComponent();
Thread t = new Thread(() => { this.label1.Text = "test"; });
t.IsBackground = true;
t.Start();
}
As discussed in many other posts, it won't work. Thread t ...
has to be replaced with something like Thread t = new Thread(()=> { this.label1.Invoke((Action)(() => { this.label1.Text = "test"; })); });
to fix it, but having in mind, that the STA should marshall this.label1.Text = "test";
to the mainthread, why do I still get the invalid cross-thread access error?
Edit Solved:
Accepted Answer:
[STAThread]
(and[MTAThread]
) are only related to working with COM interop.
Since the Label-Object seems to be just a wrapper for a Win32 control, it is no COM-Object (as wrongly expected from me due to the blockquote at the beginning of the question) and so calls will not be marshalled. There are checks for calls from other threads inside the wrapper, but marshalling via (Begin)Invoke has to be done by the developer.
The coming up question is of course: how could the wrapper be modified, so this is done automatically and downwardly compatible.. but that's another topic, I guess.