0

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.

3
Contributors
8
Replies
9
Views
6 Years
Discussion Span
Last Post by PierlucSS
0

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.

Edited by nick.crane: n/a

0

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

Edited by nick.crane: n/a

0

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();
        }
0

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;
            }
        }
    }

Edited by nick.crane: n/a

1

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.

0

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.

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.