Sunday, September 20, 2009

Cross-thread operation not valid.

In window application , when you need to use Threading and access control inside that thread, then you get this error “Cross-thread operation not valid.” The reason behind this control is working under main thread and you create another thread in which you are trying to access control.

There are two ways to solve this error.

1. Set property in Form constructor.
You need to set static property CheckForIllegalCrossThreadCalls  of control class to false value. This will disable cross thread checking.
       
       public Form1()
       {
         InitializeComponent();
           Control.CheckForIllegalCrossThreadCalls = false;
       }

Sample Code (C#):

public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Test));
            th.Start(1000);           
        }

        public void Test(object o)
        {
            for (int i = 0; i < 10; i++)
            {
                label1.Text = System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + " --- " + i.ToString();
                System.Threading.Thread.Sleep(int.Parse(o.ToString()));
            }
        }
    }



2. Use delegate and event.

Sample Code (C#) :

public partial class Form1 : Form
    {
        delegate void SetLabelText(string str);
        SetLabelText setLabel1Text = null;
        public Form1()
        {
            InitializeComponent();
            setLabel1Text = new SetLabelText(Label1Text);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            System.Threading.Thread th = new System.Threading.Thread(new System.Threading.ParameterizedThreadStart(Test));
            th.Start(1000);           
        }

        public void Test(object o)
        {
            for (int i = 0; i < 10; i++)
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(setLabel1Text, System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() + " --- " + i.ToString());
                }
                System.Threading.Thread.Sleep(int.Parse(o.ToString()));
            }
        }

        public void Label1Text(string str)
        {
            label1.Text = str;
        }
    }

Please give your comment on this.