I am using visual studio 2008 with C# developing an window application,
I want to displsy blinking text with marquee on label using thread.But it generates error :--Cross thread error. What is this and pls solve my problem.

Recommended Answers

All 8 Replies

Any changes to UI objects must be done by the UI thread.
You need to invoke the function call that changes the text.
There are several examples of using delegates and invoking, just do a search and you should find something. If not, just ask.

nick.crane pls send me some links.

OK, so there are a few more than I thought.
Give me a minute and I'll put together an example.

Sorry I took so long, I had to do deal with a work issue.

This class uses a delegate and invoke to ensure that the text box text is updated on the UI thread.

class TaskThreadClass
    {
        private TextBox textbox;

        public string newText;

        public TaskThreadClass(TextBox tb)
        {
            textbox = tb;
        }

        public void StartThreadTask()
        {
            // create new thread and run it
            System.Threading.Thread t = new System.Threading.Thread(ThreadTask);
            t.Start();
        }

        private void ThreadTask()
        {
            // 2 second delay to simulate doing something
            System.Threading.Thread.Sleep(2000);
            // update textbox with result
            // Don't realy need to pass this as a parameter but I do to 
            // show using a delegate with parameters.
            UpdateTextBox(newText);
        }

        // delegate we define ourselves
        // Note: the EventHandlers are also delegates with parameters
        public delegate void UpdateTextBoxHandler(string Text);

        // Don't realy need to pass value as a parameter
        // I do to show using a delegate with parameters.
        private void UpdateTextBox(string Text)
        {
            if (textbox == null)
                return;

            // test if we need to invoke this method for the textbox
            if (textbox.InvokeRequired)
            {
                // invoke this method using the delegate handler and pass parameters
                textbox.Invoke(new UpdateTextBoxHandler(UpdateTextBox), new object[] { Text });
            }
            else
            {
                // change the UI object value
                textbox.Text = Text;
            }
        }
    }

I added a button on my form to test this.

TaskThreadClass testObj;
        private void button7_Click(object sender, EventArgs e)
        {
            if (testObj == null)
            {
                testObj = new TaskThreadClass(this.textBox1);
            }
            testObj.newText += "New text ";
            testObj.StartThreadTask();
        }

Just thought of another way.
Use a static helper method.
This is a more general version using Control instead of TextBox.

// code called in background thread
    UpdateUIControlClass.UpdateControlText(form1.textbox1, newText);


    // control update helper class
    static class UpdateUIControlClass
    {
        private delegate void UpdateControlTextHandler(Control ctrl, string Text);

        public static void UpdateControlText(Control ctrl, string Text)
        {
            // test if we need to invoke this method for the control
            if (ctrl.InvokeRequired)
            {
                // invoke this method using the delegate handler and pass parameters
                ctrl.Invoke(new UpdateControlTextHandler(UpdateControlText), new object[] { ctrl, Text });
            }
            else
            {
                // change the UI object value
                ctrl.Text = Text;
            }
        }
    }

If you want something more simple do the following:

if(ctrl.InvokeRequired)
{
   ctrl.Invoke( (MethodInvoker)delegate
   {
      ctrl.Text = "hola!";
   }); 
}

The only difference between this and nick's method, is that he will have a specific delegate (recallable), and I'm just making one on the fly.

If you want something more simple do the following:

if(ctrl.InvokeRequired)
{
   ctrl.Invoke( (MethodInvoker)delegate
   {
      ctrl.Text = "hola!";
   }); 
}

The only difference between this and nick's method, is that he will have a specific delegate (recallable), and I'm just making one on the fly.

Thanks. I didn't know about that.

Thanks. I didn't know about that.

No problem :) I've learned that here anyways hehe :)

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.