【问题标题】:Multithreading with textbox control [duplicate]带有文本框控件的多线程[重复]
【发布时间】:2013-03-22 20:28:55
【问题描述】:

我是 C# 的初学者。而且我不明白为什么接下来的两个示例会给出不同的结果。我在msdn 中使用微软示例。在第一个示例中,它在文本框中显示一个数字。在第二个示例中,它为每个线程显示从 0 到 1000 的所有数字。

第一个例子:

    delegate void SetTextCallback(object text);

    private void WriteString(object text)
    {

        if (this.textBox1.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(WriteString);
            this.BeginInvoke(d, new object[] { text });
        }
        else
        {
            for (int i = 0; i <= 1000; i++)
            {
                textBox1.Text = text.ToString();
            }

        }

    }

第二个例子:

    private void MyApp_Load(object sender, EventArgs e)
    {
        System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false;

    }

    private void WriteString(object text)
    {
        for (int i = 0; i <= 1000; i++)
        {
            textBox1.Text = text.ToString();
        }
    }

以及调用这些示例的方法

    private void button1_Click(object sender, EventArgs e)
    {

        Thread th_1 = new Thread(WriteString);
        Thread th_2 = new Thread(WriteString);
        Thread th_3 = new Thread(WriteString);
        Thread th_4 = new Thread(WriteString);

        th_1.Priority = ThreadPriority.Highest; 
        th_2.Priority = ThreadPriority.BelowNormal; 
        th_3.Priority = ThreadPriority.Normal; 
        th_4.Priority = ThreadPriority.Lowest; 

        th_1.Start("1");
        th_2.Start("2");
        th_3.Start("3");
        th_4.Start("4");

        th_1.Join();
        th_2.Join();
        th_3.Join();
        th_4.Join();
    }

【问题讨论】:

  • 我一定错过了什么。这两个示例似乎都只会将单个数字写入文本字段(“1”、“2”、“3”或“4”),而不会从 0 到1000,也不会一次显示多个数字。除非它可能与从后台线程写入 Text 属性的不一致行为有关?
  • 第二个示例通过直接从线程访问 GUI 元素来召唤 Cthulhu。使用 System.Console.WriteLine() 或类似方法来实际比较它们。
  • 嗨@DasKrümelmonster!如何在 Win.Forms 应用程序中使用 System.Console.WriteLine()?
  • 你试过了吗?默认情况下,VS 在右下窗格中显示输出。 (至少它对我有用,如果没有看到这里:stackoverflow.com/questions/5301232/…
  • @goodspeed:你不能使用console.writeline(),正如类名所表明的那样,它只用于控制台应用程序。但是,Winforms 中的等效方法是使用 MessageBox.Show()。示例:Console.Writeline(resultString) as MessageBox.Show(Result: {0}", resultString)。

标签: c# multithreading


【解决方案1】:

好吧,我在我的 VS 中进行了分析。我也是 C# 的新手。但我可以推断如下:

方案一:

Begin Invoke 是调用方法的异步方式。因此,它最后只显示一个结果。如果您在 VS 中缓慢地执行 F11 并观察,并不是每次都得到结果 4。但有时当您执行 F11 并在某些地方逐步进行时(我的意思是延迟),由于多线程,有时您也会得到 3。您应该记住,多线程永远不会一直以相同的方式运行,这意味着假设如果多线程中的应用程序或模块一次给您一个结果,两次和 10 次,您不能确定它是正确的或优化的代码。因为在客户端环境中,由于其自​​身的行为,它可能会导致不同的结果,这些结果可能在调试时被忽视,甚至不会发生。我在一个不错的博客中读到它。

方案二:

由于它是多线程的,我可以看到不同线程的行为在不同的时间被调用,并且当它完成工作时,我看到文本框在几秒钟内快速更新,这是肉眼无法注意到的,但最终结果是显示一个数字。此外,您确实检查了跨线程调用)当您使用 F11 进入每一行代码时,您会发现这种行为并很好地理解)并且您命令不要捕获它。这使得线程在第二种情况下协同工作。

这是我的推论,但我可以说,太老套了!我没有自信地声称这一点,而只是我的观察:)

让一些伟大的人发表他们的观点来帮助我们:)

干杯

【讨论】:

  • 感谢您的出色回答。据我了解,program1 一次只显示一个数字...但是为什么.. 我可以显示来自程序一中每个线程的所有 1000 个数字吗?
  • 好吧,我真的很抱歉,我不能做你刚才问的事情 :( 如果有人帮助我们俩,我也会很高兴 :) 干杯
  • richTextBox1.AppendText(text.ToString());@Divine 如果你添加这个而不是 textBox1.Text = text.ToString();您将看到 program1 显示每个线程的所有数字。我认为这就像 Java 中的同步。在 program2 线程中同时显示所有数字,因为代码中没有“同步”。
  • @goodspeed: 太棒了,谢谢 :) 你做到了 :) 干杯
猜你喜欢
  • 2012-04-02
  • 1970-01-01
  • 1970-01-01
  • 2010-11-18
  • 1970-01-01
  • 2015-01-15
  • 2019-04-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多