Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on
You will get following error when you try to update a windows form control from a separate thread.
"Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on."
This article guides you on how to overcome this problem.
Problem
To reproduce this error, insert a progress bar control (progressbar1) on your form and insert a button(btnStart).
01.
private
void
btnStart_Click(
object
sender, EventArgs e)
02.
{
03.
progressBar1.Minimum = 0;
04.
progressBar1.Maximum = 100;
05.
06.
System.Threading.Thread t1 =
new
System.Threading.Thread(startProgress);
07.
t1.Start();
08.
}
09.
void
startProgress()
10.
{
11.
for
(
int
i = 0; i {
12.
progressBar1.Value = i;
13.
System.Threading.Thread.Sleep(100);
14.
}
15.
}
Solution
01.
private
void
btnStart_Click(
object
sender, EventArgs e)
02.
{
03.
progressBar1.Minimum = 0;
04.
progressBar1.Maximum = 100;
05.
06.
System.Threading.Thread t1 =
new
System.Threading.Thread(startProgress);
07.
t1.Start();
08.
}
09.
void
startProgress()
10.
{
11.
for
(
int
i = 0; i {
12.
SetControlPropertyValue(progressBar1,
"value"
, i);
13.
System.Threading.Thread.Sleep(100);
14.
}
15.
}
Note how SetControlpropertyValue function is used above. Following is it's definition.
01.
delegate
void
SetControlValueCallback(Control oControl,
string
propName,
object
propValue);
02.
private
void
SetControlPropertyValue(Control oControl,
string
propName,
object
propValue)
03.
{
04.
if
(oControl.InvokeRequired)
05.
{
06.
SetControlValueCallback d =
new
SetControlValueCallback(SetControlPropertyValue);
07.
oControl.Invoke(d,
new
object
[] { oControl, propName, propValue });
08.
}
09.
else
10.
{
11.
Type t = oControl.GetType();
12.
PropertyInfo[] props = t.GetProperties();
13.
foreach
(PropertyInfo p
in
props)
14.
{
15.
if
(p.Name.ToUpper() == propName.ToUpper())
16.
{
17.
p.SetValue(oControl, propValue,
null
);
18.
}
19.
}
20.
}
21.
}
You can apply same solution to any windows control. All you have to do is, copy SetControlValueCallback delegate and SetControlPropertyValue function from above code. For example if you want to set property of a label, use SetControlPropertyValue function.
SetControlPropertyValue(Label1, "Text", i.ToString());
Make
sure you supply property value in correct type. In above example Text
is a string property. This is why I am converting variable i to string.
No comments:
Post a Comment