"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?