"Cross-thread operation not valid: Control 'lstPrime' accessed from a thread other than the thread it was created on." = How can we solve this error??

Recommended Answers

All 8 Replies

Threading is a very complicated thing, and you can't access a control from another thread than the one it was created on which is almost always the GUI thread, or the thread that is started when the application runs.

The best idea here is to build a application modal that doesn't rely on the controls hosing the information, but just displaying it.

you have given no information about your error, just the error message and that's USELESS out of context. It could be that you need to pass a list of files or something to the worker thread as an object, or it could be that you need to use a delegate and invoke a call onto the control. But Its hard to tell. Post your code, We will help you.

One way is usign delegates, another one which is easier for smaller applciations is using the BackgroundWorker class, here is an example:

void StartWork()
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += new ProgressChangedEventHandler(worker_ProgressChanged);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
            worker.DoWork += new DoWorkEventHandler(worker_DoWork);
            worker.RunWorkerAsync(OptionalObject);// can pass any object you may need to the method where you will do the actual prcessing
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = (BackgroundWorker)sender;
            // do your threading work here

            // first argument is percentage of your work complete, can be anything really
            // second argument you can pass any object you may need to update your GUI thread
            worker.ReportProgress(0, OptionalObject);
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // this will run once your thread has finished its work
        }

        void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            // here you can update your GUI, small example here
            string title = (string)e.UserState;
            MyLabel.Text = title;
        }

Hi,
Here int the below given codes I am getting the error "Cross-thread operation not valid: Control 'frmWish' accessed from a thread other than the thread it was created on."

Please show me the exact codings required in the below mentioned codes to avoid the error.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Random_Message
{
    public partial class frmWish : Form
    {
        int x = 0;
        int y = 0;

        public frmWish()
        {
            InitializeComponent();
        }
        public void Display()
        {
            Random objRandom = new Random();                   
            for (int index = 1; index <= 100000; index++)
            {
                x = objRandom.Next(200);
                y = objRandom.Next(200);
                lblMessage.Left = x;
                lblMessage.Top = y;
                Thread.Sleep(500);                
            }
        }

        private void frmWish_Load(object sender, EventArgs e)
        {
            Thread draw = new Thread(new ThreadStart(Display));
            draw.Start();

        }
    }
}

Threading is a very complicated thing, and you can't access a control from another thread than the one it was created on which is almost always the GUI thread, or the thread that is started when the application runs.

The best idea here is to build a application modal that doesn't rely on the controls hosing the information, but just displaying it.

you have given no information about your error, just the error message and that's USELESS out of context. It could be that you need to pass a list of files or something to the worker thread as an object, or it could be that you need to use a delegate and invoke a call onto the control. But Its hard to tell. Post your code, We will help you.

here is the code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace DaniwebThreading.DancingLabels
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Thread draw;

        private void Form1_Load(object sender, EventArgs e)
        {
            draw = new Thread(new ThreadStart(Display));
            draw.Start();
        }

        public void Display()
        {
           bool doloop = true;
           int X;
           int Y;

            Random objRandom = new Random();
           // for (int index = 1; index <= 100000; index++) //use while loop to keep it going forever!
            while(doloop)
            {
                X = objRandom.Next(200);
                Y = objRandom.Next(200);
                moveLabel(new Point(X, Y));
                Thread.Sleep(500);
            }
        }

        public delegate void MoveLabelDelegate(Point P);

        public void moveLabel(Point P)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MoveLabelDelegate(moveLabel), P);
            }
            else
            {
                lblMessage.Location = P;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            draw.Abort(); //kill the thread.
        }
    }
}

you need a delegate to usher the call on to the GUI thread by calling invoke. The trick here is creating a method that will check if its required, and if so invoke its self using the delegate. Its a good idea to create these type methods for all the controls you with to update information for.

The form closing event here is used to abort the thread so you don't get an exception when you close the form where the draw thread is still trying to modify the disposed control.

Threading gets complicated. Good luck with your endeavors.

I have used the under-mentioned codes but the label is idle at one place. What changes is required to move it randomly on a form.

Please solve.

here is the code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace DaniwebThreading.DancingLabels
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Thread draw;

        private void Form1_Load(object sender, EventArgs e)
        {
            draw = new Thread(new ThreadStart(Display));
            draw.Start();
        }

        public void Display()
        {
           bool doloop = true;
           int X;
           int Y;

            Random objRandom = new Random();
           // for (int index = 1; index <= 100000; index++) //use while loop to keep it going forever!
            while(doloop)
            {
                X = objRandom.Next(200);
                Y = objRandom.Next(200);
                moveLabel(new Point(X, Y));
                Thread.Sleep(500);
            }
        }

        public delegate void MoveLabelDelegate(Point P);

        public void moveLabel(Point P)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MoveLabelDelegate(moveLabel), P);
            }
            else
            {
                lblMessage.Location = P;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            draw.Abort(); //kill the thread.
        }
    }
}

you need a delegate to usher the call on to the GUI thread by calling invoke. The trick here is creating a method that will check if its required, and if so invoke its self using the delegate. Its a good idea to create these type methods for all the controls you with to update information for.

The form closing event here is used to abort the thread so you don't get an exception when you close the form where the draw thread is still trying to modify the disposed control.

Threading gets complicated. Good luck with your endeavors.

Thanks...The code is working but even after closing the form, continues the debugging until I am stopping the it.

here is the code.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace DaniwebThreading.DancingLabels
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Thread draw;

        private void Form1_Load(object sender, EventArgs e)
        {
            draw = new Thread(new ThreadStart(Display));
            draw.Start();
        }

        public void Display()
        {
           bool doloop = true;
           int X;
           int Y;

            Random objRandom = new Random();
           // for (int index = 1; index <= 100000; index++) //use while loop to keep it going forever!
            while(doloop)
            {
                X = objRandom.Next(200);
                Y = objRandom.Next(200);
                moveLabel(new Point(X, Y));
                Thread.Sleep(500);
            }
        }

        public delegate void MoveLabelDelegate(Point P);

        public void moveLabel(Point P)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new MoveLabelDelegate(moveLabel), P);
            }
            else
            {
                lblMessage.Location = P;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            draw.Abort(); //kill the thread.
        }
    }
}

you need a delegate to usher the call on to the GUI thread by calling invoke. The trick here is creating a method that will check if its required, and if so invoke its self using the delegate. Its a good idea to create these type methods for all the controls you with to update information for.

The form closing event here is used to abort the thread so you don't get an exception when you close the form where the draw thread is still trying to modify the disposed control.

Threading gets complicated. Good luck with your endeavors.

Query is solved. Program is running successfully.

I have used the under-mentioned codes but the label is idle at one place. What changes is required to move it randomly on a form.

Please solve.

Please mark the thread as solved using the "mark as solved"

Sorry it took you some time to adapt the code. I was going to post the whole project but I figured you would figure it out, as you have.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.