Pankaj
Pankaj

Reputation: 10115

Delegates in Threads and Anonymous methods - Update controls in new Thread

I was using multithreading in my window form. Following is my class. I have a label control in my designer and under the newly created thread I am updating it's text property.

Following is the case when I encapsulated the function "UpdateLabel" in a delegate "Del". and it works fine.

public partial class DynamicType : Form
    {
        delegate void Del(String x);

        public DynamicType()
        {
            InitializeComponent();
        }

        private void DynamicType_Load(object sender, EventArgs e)
        {
            System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(StartThread));
            t.Start();
        }

        private void StartThread()
        {
            this.Invoke(new Del(UpdateLabel), new object[] { "Hi" });
        }

        private void UpdateLabel(String str)
        {
            label1.Text = str;
        }
    }

I have a another case called Anonymous Methods. Upon implementing the Anonymous methods in the following methods. Following are the definitions.

private void StartThread()
        {
            UpdateLabel("Hi");
        }



private void UpdateLabel(String str)
        {
            Del Label = delegate(String k)
             {
                 label1.Text = k;

             };
            Label("hi");
        }

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

My query is in the previous case I was using the delegates and it worked fine and in case of anonymous methods I removed the extra functions by directly instantiating the delegates and tried to update the label control text property and it gave the crash as mentioned above. Reason?

Upvotes: 0

Views: 3465

Answers (1)

Heinzi
Heinzi

Reputation: 172448

In the first example, you are calling the label update in the UI thread (via Form.Invoke). This is correct and works:

this.Invoke(new Del(UpdateLabel), new object[] { "Hi" });

In the second example, you are creating a delegate in the background thread and starting that delegate in the background thread. That doesn't work, because the background thread is not allowed to update the UI:

Del Label = delegate(String k) { label1.Text = k; }; 
Label("hi");   // runs in the same thread

To solve this, you have to use this.Invoke to execute the delegate in the UI thread:

Del Label = delegate(String k) { label1.Text = k; }; 
this.Invoke(Label, new object[] {"hi"});   // runs in the UI thread

Upvotes: 1

Related Questions