"Cross-thread operation is not valid" exception when trying to get value of comboBox

.net, c#, multithreading, thread-safety, winforms

Solution

Right now, you're getting the value from the `TextBox`, via: `t.setTitle(textBox1.Text);`. This will also fail.

Should I need to create a similar get function? Or any other solution available?

Yes, you need an option for get. I would recommend not using reflection and text, however, and rework this to use generic methods and lambdas.

public static void SetControlPropertyThreadSafe<T>(T control, Action<T> action) where T : Control
    {
            if (control.InvokeRequired)
            {
                control.Invoke(action);
            }
            else
            {
                action();
            }
    }

This would allow you to write this strongly typed, ie:

Global.SetControlPropertyThreadSafe(button1, b => b.Text = "Working...");

You can also make a strongly typed get method:

public static U GetControlPropertyThreadSafe<T,U>(T control, Func<T,U> func) where T : Control
{
     if (control.InvokeRequired)
     {
         return (U)control.Invoke(func, new object[] {control});
     }
     else
     {
         return func(control);
     }
}

Which then lets you write:

 t.setTitle(Global.GetControlPropertyThreadSafe(textBox1, t => t.Text));

You could also use the same methods for getting and setting the combo box items.

Problem

``` "Cross-thread operation is not valid" exception ``` I experienced this exception many times, but all those times I was setting the value of a control. That time I solved using a function called `SetControlPropertyThreadSafe()`, which was suggested by someone on stackoverflow.com only. But this time I am getting this exception when I am trying to get the value of comboBox. Here is the code: ``` string cat; private void button1_Click(object sender, EventArgs e) { if (textBox1.Text.Trim().Length > 20) { System.Threading.Thread t = new System.Threading.Thread(addQuickTopic); t.Start(); } else MessageBox.Show("The length of the title must be greater than 20", "Title length invalid", MessageBoxButtons.OK, MessageBoxIcon.Exclamation); } public string tTitle=""; void addQuickTopic() { Global.SetControlPropertyThreadSafe(button1, "Text", "Working..."); Global.SetControlPropertyThreadSafe(button1, "Enabled", false); Topic t = new Topic(); t.setTitle(textBox1.Text); t.setDescription(" "); t.setDesID(Global.getMd5Hash(Common.uid+DateTime.Today.ToString()+DateTime.Today.Millisecond.ToString())); t.setUsrID(Common.uid); t.setReplyToID(""); t.setConDate("0"); cat = CategoryList.SelectedValue.ToString(); ``` As you can see I am getting the textBox1.Text directly without applying any thread safe operation. But at the last line when trying to fetch comboBox's selected value, I am getting this exception. So can any one please suggest me what to do in this situation? Following is the code for my thread safe function for setting control's value: ``` public static void SetControlPropertyThreadSafe(Control control, string propertyName, object propertyValue) { try { if (control.InvokeRequired) { control.Invoke(new SetControlPropertyThreadSafeDelegate(SetControlPropertyThreadSafe), new object[] { control, propertyName, propertyValue }); } else { control.GetType().InvokeMember(propertyName, BindingFlags.SetProperty, null, control, new object[] { propertyValue }); } } catch (Exception) { } } ``` Should I need to create a similar `get` function? Or any other solution available?

Original source

Related problems