2

why when i'm runing the program the for's doesn't run in Parallel after the "one" for is finish the "two" for begin thanks in advance (im a noobie in C#)

    private void button1_Click(object sender, EventArgs e)
    {

      Thread  t = new Thread(new ThreadStart(Threadtest));
      t.Start();

      for(int i = 0 ;i<5;i++)
         richTextBox1.Text = richTextBox1.Text + "one"+i+"\n";
    }
    private void Threadtest()
    {
        for (int i = 0; i < 5; i++)
        {
            MethodInvoker action = delegate { richTextBox1.Text = richTextBox1.Text + "two" + i + "\n"; };
            richTextBox1.Invoke(action);
        }

    }
famr d
  • 21
  • 1

3 Answers3

3

You would need to do it with many more than 5 iterations. The thread isn't even getting fired up before your "one" stuff is completed.

Also, because your "one" code never sleeps, it may run to completion before it allows your marshalled code via Invoke to run at all. Invoke/BeginInvoke cause the code to run on the UI thread - that can't happen until the UI thread has no other work to do.

DoEvents would enable that. But it's not something you should normally use for multi-threading. It just helps for this illustration of multi-threading.

Andrew Barber
  • 39,603
  • 20
  • 94
  • 123
  • Invoke is blocking, if called off-gui, it'll never be able to call the action. – payo Mar 22 '12 at 23:35
  • 1
    @payo I believe you are misunderstanding the nature of the difference between Invoke and BeginInvoke. From what you say, Invoke is completely useless. The only difference is that Invoke waits for the action to be completed - still on the UI thread. BeginInvoke *also* runs on the UI thread, but doesn't wait for completion. – Andrew Barber Mar 22 '12 at 23:39
  • thank you - yes, invoke from gui thread causes deadlock. thus only call invoke if `InvokeRequired`. http://stackoverflow.com/questions/2055960/control-invoke-getting-stuck-in-hidden-showdialog – payo Mar 22 '12 at 23:47
  • To paraphrase Eric Lippert in one of his posts, assume a thread takes about a century to start, because from the CPU's perspective it takes about that long. Never assume that a thread will start "fast enough to do x". That said, Payo is actually correct. Because the UI thread is still processing the button click event, the windows messages from the Invoke calls will queue up until the UI thread has finished processing the "ones" – Chris Shain Mar 22 '12 at 23:56
  • @ChrisShain That's what my second/third paragraph say. But this has nothing to do with whether they are using Invoke or BeginInvoke. But as payo notes, you shouldn't call Invoke from the UI thread. (this code doesn't do that) – Andrew Barber Mar 22 '12 at 23:58
2

EDIT 3: corrected again

The threaded loop is not 'weaving' updates because your non-threaded loop it is not returning control to the main gui event loop, which would process the events from your thread. Thus, it all happens afterwards. One solution to 'see' this happen would be to spawn two threads.

payo
  • 4,501
  • 1
  • 24
  • 32
  • 1
    even that doesn't run the actions in parallel, it simply submits them all to be run serially by the event thread. this just allows them to be "queued" in parallel – John Gardner Mar 22 '12 at 23:30
  • fixed - I started in the wrong state of mind because I misread his question to begin with. – payo Mar 22 '12 at 23:32
1

The GUI environment is single threaded. And there is nothing you can do about it. That is how GUIs in Windows are designed.

Invoke is only queuing the operations on the GUI thread to be completed after the current operation, button1_Click, is done.

You can use Appllication.DoEvents to process anything queued before continuing, but the UI is still single threaded.

Nick Whaley
  • 2,729
  • 2
  • 21
  • 28