【问题标题】:Winforms Cross thread operation is valid sometimes. Can somebody explain?Winforms 跨线程操作有时有效。有人可以解释一下吗?
【发布时间】:2016-05-27 17:54:33
【问题描述】:

在 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();

我看到了this post,它解释了当控件不在视图中时可能会发生这种情况。但就我而言,控件始终可见。

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

【问题讨论】:

  • 出于好奇,是不是每次都抛出同一个异常?

标签: c# multithreading winforms


【解决方案1】:

您链接到的答案的第一句话仍然适用于您“您的代码根本上是错误的,但这并不意味着您一定会被提醒。”

API 的制造者(Microsoft)告诉您,您不应该在不在 UI 线程上的控件上调用任何内容。如果您不遵守他们的指示,他们没有责任警告您。是的,它现在不会抛出异常,但这并不意味着它以后永远不会抛出异常或给你意外的行为。

【讨论】:

  • 你引用的那句话是对的。但是那个帖子也说当控件不可见时它不会爆炸。就我而言,控件始终可见。有没有可能的进一步解释?
  • @BharatGupta 人很懒惰,编写Image 类的人并没有花额外的时间对每个可能的属性进行跨线程检查调用。所以Image 中定义的新属性可能不会警告您,但它从Control 继承的属性会。警告是一件方便的事情,只是因为没有人对你大喊你做错了并不一定意味着你做对了,它只是意味着现在没有人想大喊大叫。
  • 您的回复很有道理。是的......我很喜欢你的回复:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-22
  • 2016-12-12
  • 2015-06-29
  • 2017-11-05
相关资源
最近更新 更多