-2

I am using VS 2012. Can anyone give a simple example, why do I need control.Invoke / BeginInvoke when using other thread. I tried to change text on a textbox via other thread, but everything just work fine. I know that in such cases the change must be called from the gui thread. But i can not find example when something doesn't work from the thread also. thank you. Liron

for example: I have this code, but it's just works fine:

    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);
        }
    }
adv12
  • 8,443
  • 2
  • 24
  • 48
  • Without sample code we can't tell you *why* your method worked, or if it's *even* right-proper threading. – Der Kommissar May 19 '15 at 20:20
  • possible duplicate: http://stackoverflow.com/questions/34510/what-is-a-race-condition – adv12 May 19 '15 at 20:21
  • Its a timing issue, try updating a lot of controls quickly, you'll find out why. Doing it quickly (and a lot of them) just illustrates the problem, it doesn't mean its not happening with a single control. It may not crash today, or tomorrow, but eventually you'll get it, randomly. – Ron Beyer May 19 '15 at 20:22
  • I have this code for example, but everything just 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); } } – user3344394 May 19 '15 at 20:26
  • 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); } } – user3344394 May 19 '15 at 20:26
  • @user3344394 Please add it to your question. – Der Kommissar May 19 '15 at 20:28
  • I added the code to the question. thanks in advance – user3344394 May 19 '15 at 20:35

1 Answers1

2

Okay, using your example code, suppose that you have a button in your UI that, when clicked, checks textBox1.Text and, if it's "aaaaa", changes the text to "peanut butter!" Suppose the text is "aaaaa" and you happen to click the button immediately after the textBox1.Text get method is called in ChangeText. On the GUI thread, you read the current value of textBox1.Text, you discover that the property is equal to "aaaaa", you set textBox1.Text to "peanut butter!", and ChangeText (on the background thread) calls textBox1.Text's set method to update it to "aaaaaa". What should happen is that the text gets set to "peanut butter!a", but it's as though you never changed anything from the GUI thread. This happens because the work being done by your background and foreground threads was interleaved. This is called a race condition, and it can be avoided by calling Invoke or BeginInvoke to make sure only one thread is accessing/mutating data at the same time.

The reason you rarely see this sort of problem in your code is that computers are really fast and the likelihood of clicking at just the right time for this sort of bug to manifest is very low. Generally, the busier competing threads are, the more likely you are to see race conditions lead to problems.

adv12
  • 8,443
  • 2
  • 24
  • 48