Multithreading in Windows Forms application results in exception "Cross-thread operation not valid"

Viewed 55

I am fighting with a tutorial from here:

https://www.geeksforgeeks.org/c-sharp-multithreading/

I try to reuse this code with windows forms, but with no success. I have modified the code to this form, using two richtextboxes:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;

namespace Multithreading
{
    /// <summary>
    /// Description of MainForm.
    /// </summary>
    public partial class MainForm : Form
    {
        public MainForm()
        {
            //
            // The InitializeComponent() call is required for Windows Forms designer support.
            //
            InitializeComponent();
            
            //
            // TODO: Add constructor code after the InitializeComponent() call.
            //
            Thread thr1 = new Thread(method1);
            Thread thr2 = new Thread(method2);
            
            thr1.Start();
            thr2.Start();
        }

        public void method1()
        {
            // It prints numbers from 0 to 10
            for (int I = 0; I <= 10; I++) 
            {
                richTextBox1.Text += "Method1 is: "+ I  + Environment.NewLine;  

                if (I == 5)
                {
                    Thread.Sleep(6000);
                }
            }
        }
 
        public void method2()
        {
            // It prints numbers from 0 to 10
            for (int J = 0; J <= 10; J++) 
            {
                richTextBox2.Text += "Method2 is: "+ J  + Environment.NewLine;  
            }
        }
    }
}

...and I get an error after 6 seconds:

Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on

I can't get why the first five numbers can be read (method 1) and all numbers from method 2 too, and after Thread.Sleep(6000) there is an error :(

It's my first time with multithreading, any help will be appreciated.

1 Answers

You cannot update the UI from any other thread than the UI thread. There are numerous questions regarding this, for example Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on.

The guide you are following works since it is only uses the console for output, and all the methods in the Console-class are thread safe. In general, static methods should be thread safe, since they would otherwise be difficult to use in a multi threaded program. As far as I know, all static methods provided by the framework follows this guideline. But there is nothing intrinsic about static methods that make them thread safe, so be careful and read the documentation. You should also assume that non-static methods are not thread safe, unless otherwise noted.

I would recommend starting by doing a fair amount of reading about thread safety and guidelines before doing anything serious involving threads. There are lots of potential hazards, and most of them are much more difficult to debug than this one.

I would also suggest following an newer guide, creating threads manually is an outdated method, the modern way is to use tasks and async/await. This provides a much more convenient method to do some work in the background, and update the UI with the result once it is done.

Related