【问题标题】:C# Winform - Change control via a thread works fine?C# Winform - 通过线程更改控制工作正常吗?
【发布时间】:2015-05-19 20:19:22
【问题描述】:

我正在使用 VS 2012。谁能举个简单的例子,为什么我需要 control.Invoke / BeginInvoke 使用其他线程时。 我试图通过其他线程更改文本框中的文本,但一切正常。我知道在这种情况下,必须从 gui 线程调用更改。 但是当线程也无法正常工作时,我找不到示例。 谢谢。 利隆

例如:我有这段代码,但它工作正常:

    private void button1_Click(object sender, EventArgs e)
    {
        Thread t = new Thread(new ThreadStart(ChangeText));
        t.Start();
    }
    private void ChangeText()
    {
        for (int i = 0; i < 50; ++i)
        {
            textBox1.Text += "a";
            Thread.Sleep(100);
        }
    }

【问题讨论】:

  • 如果没有示例代码,我们无法告诉您为什么您的方法有效,或者它是否是甚至正确的线程。
  • 这是一个时间问题,尝试快速更新很多控件,你会发现原因。快速(而且很多)只是说明问题,并不意味着它不会发生在单个控件上。它可能不会在今天或明天崩溃,但最终你会随机得到它。
  • 例如我有这段代码,但一切都只是 private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(new ThreadStart(ChangeText)); t.Start(); } private void ChangeText() { for (int i = 0; i
  • private void button1_Click(object sender, EventArgs e) { Thread t = new Thread(new ThreadStart(ChangeText)); t.Start(); } private void ChangeText() { for (int i = 0; i

标签: c# multithreading invoke


【解决方案1】:

好的,使用您的示例代码,假设您的 UI 中有一个按钮,单击该按钮时会检查 textBox1.Text,如果是“aaaaa”,则将文本更改为“花生酱!”假设文本是“aaaaa”,而您恰好在 ChangeText 中调用 textBox1.Text get 方法后立即单击了按钮。在 GUI 线程上,您读取 textBox1.Text 的当前值,发现属性等于“aaaaa”,将 textBox1.Text 设置为“花生酱!”,然后 ChangeText(在后台线程上)调用textBox1.Textset 方法将其更新为“aaaaaa”。 应该发生的事情是文本被设置为“花生酱!a”,但就好像您从未从 GUI 线程更改任何内容。发生这种情况是因为您的后台线程和前台线程正在执行的工作是交错的。这称为竞争条件,可以通过调用InvokeBeginInvoke 来确保只有一个线程同时访问/更改数据来避免这种情况。

您很少在代码中看到此类问题的原因是计算机运行速度非常快,而且在恰当的时间单击以显示此类错误的可能性非常低。通常,竞争线程越忙,您就越有可能看到竞争条件导致问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    相关资源
    最近更新 更多