Winforms交叉线程操作有时是有效的.有人可以解释一下吗?

Bha*_*pta 4 c# multithreading winforms

在winforms应用程序中,跨线程操作无效.据我所知,我们无法使用任何其他线程修改在UI线程中创建的控件.我们应该使用Control.Invoke方法委托任何此类修改.

我注意到了不同的行为.我们可以从其他线程修改一些属性,但不是全部.查看以下最小代码.

new Thread(() =>
{
    pictureBox1.Image = new Bitmap("path-to-file"); // Works fine. Replaces the old picture with the new one. 
}).Start();

new Thread(() =>
{
    pictureBox1.Size = new Size(100, 100); // Throws error
}).Start();

new Thread(() => {
    label1.BackColor = Color.Red; // Works fine. Changes the background color.
}).Start();

new Thread(() => {
    label1.Text = "SomeText"; // Throws error
}).Start();
Run Code Online (Sandbox Code Playgroud)

我看到这篇文章解释了当控件不在视野中时可能会发生.但在我的情况下,控件始终可见.

有人可以解释这种行为背后的原因吗?

Sco*_*ain 5

您链接的答案的第一个声明仍然适用于您"您的代码根本就是错误的,但这并不意味着您可以保证会被提醒."

API(微软)的制造商告诉你,不要在UI线程上调用控件上的任何内容.任何时候不按照他们的指示警告你并不​​是更重要的责任.是的,它现在不会抛出异常,但这并不意味着它永远不会抛出异常或在以后发生意外行为.

  • @BharatGupta人很懒,谁写了`Image`类并没有花费额外的时间将跨线程检查调用放在每个可能的属性上.所以在`Image`中定义的新属性可能不会警告你,但是它从`Control`继承的那些属性.警告是一种方便的事情,因为没有人对你大吼大叫说你做错了并不一定意味着你做得对,这只是意味着现在没有人感觉大喊大叫. (2认同)