Shabdar.org
Webshabdar.org
Cross-thread operation not valid: Control 'progressBar1' accessed from a thread other than the thread it was created on PDF Print E-mail
Written by Shabdar   
Tuesday, 25 November 2008 12:28
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).

private void btnStart_Click(object sender, EventArgs e)
{
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;

System.Threading.Thread t1 = new System.Threading.Thread(startProgress);
t1.Start();
}
void startProgress()
{
for (int i = 0; i {
progressBar1.Value = i; //You will get error at this line
System.Threading.Thread.Sleep(100);
}
}

window.google_render_ad();

Solution


private void btnStart_Click(object sender, EventArgs e)
{
progressBar1.Minimum = 0;
progressBar1.Maximum = 100;

System.Threading.Thread t1 = new System.Threading.Thread(startProgress);
t1.Start();
}
void startProgress()
{
for (int i = 0; i {
SetControlPropertyValue(progressBar1, "value", i); //This is a thread safe method
System.Threading.Thread.Sleep(100);
}
}


delegate void SetControlValueCallback(Control oControl, string propName, object propValue);
private void SetControlPropertyValue(Control oControl, string propName, object propValue)
{
if (oControl.InvokeRequired)
{
SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue);
oControl.Invoke(d, new object[] { oControl, propName, propValue });
}
else
{
Type t = oControl.GetType();
PropertyInfo[] props = t.GetProperties();
foreach (PropertyInfo p in props)
{
if (p.Name.ToUpper() == propName.ToUpper())
{
p.SetValue(oControl, propValue, null);
}
}
}
}

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.


 
{mos_fb_discuss:23}
Comments
Add New Search
+/-
Write comment
Name:
Email:
 
Website:
Title:
UBBCode:
[b] [i] [u] [url] [quote] [code] [img] 
 
 
Please input the anti-spam code that you can read in the image.
Mostafa Gaber  - Software Department Officer |196.219.57.xxx |2009-04-07 02:19:12
:kiss:



many thank; this is a powerfull solution
Simeon |87.126.67.xxx |2009-04-16 05:43:13
Thanks, pretty good example
Shahid  - Excellent |119.73.65.xxx |2009-04-16 11:22:41
Excellent
nb |203.199.118.xxx |2009-04-22 01:41:56
Hi

great example for referring.

m having a similar problem using backgroundworker.I've a progressbar working and
a collapsible panel.in background worker events i care for my main progreebar.so
wen i run my code it gives cross thread exception.



can u suggest...
Iwan |82.210.249.xxx |2009-04-23 03:52:39
Nice! But how to implement this in managed c++ code?

Best Regards
sujith  - Software programmer |123.237.132.xxx |2009-05-05 19:28:47
:)
This is very helpful solution and simple.
Thanks.
yuanna  - cross thread code in vb |203.130.203.xxx |2009-05-07 22:55:41
hi, i am using vs 2005, can i have the code in vb programming language? many
thanks,
yuanna.
yuanna  - cross thread progress bar |203.130.203.xxx |2009-05-07 23:01:59
i am making a splash screen with loading bar, but one line didnt work:

Option Explicit On
Option Strict On

Public Class FrmSplash

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
Me.Timer1.Enabled = True
End Sub


Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Timer1.Tick

ProgressBar1.Value += 5 // doesnt work here
If ProgressBar1.Value = 30 Then
Label4.Text = "Loading."
End If
If ProgressBar1.Value = 50 Then
Label4.Text = "Loading.."
End If
If ProgressBar1.Value = 80 Then
Label4.Text = "Loading..."
End If
If ProgressBar1.Value = 100 Then
Label4.Text = "Completed"
Timer1.Dispose()
Me.DialogResult = Windows.Forms.DialogResult.OK
FadeOut(Me, 0.01)
End If
End Sub
Sub FadeOut(ByVal iForm As Form, Optional ByVal speed As Double = 0.1, Optional
ByVal disposeForm As Boolean = False)
Dim i As Double
For i = 1 To 0 Step -speed
iForm.Opacity = i
Next
If disposeForm = True Then
iForm.Dispose()
End If
End Sub

End Class

can anybody help?

many thanks
Prateek  - re: cross thread progress bar |68.166.101.xxx |2009-06-22 08:47:17
Quote:

ProgressBar1.Value += 5[/b] // doesnt work here

Change this to:
ProgressBar1.Value = ProgressBar1.Value + 5


hope this helps,

Prateek
satya  - re: how to do with the function like form1.show() |122.169.136.xxx |2009-10-16 02:57:10
ok this works very well thanks a lot :cheer: .Is this code works for multiple
threads ? all threads share and update same the label :?:
Visveswaraiah  - WebBrowser1.Navigate(strUrl) |220.227.50.xxx |2009-06-03 20:58:02
It is wonderful solution you have given, but i dont know how to call a method
like Navigate using your function, Can you tell me how to call Navigate method
of a web browser control inside thread, kindly help me please
Nic  - Very useful |194.78.192.xxx |2009-06-11 23:46:23
Thanks
Vinod |24.14.127.xxx |2009-06-14 18:47:44
awesome solution
bie  - Datagrid |222.124.204.xxx |2009-06-21 21:39:53
how about datagrid????
Chetan |76.25.64.xxx |2009-07-16 09:34:59
Waw.. Great Work man.. Thanks for this.. Dou know know how to implement this
with Grid.datasource property.
I am working on Critical deadline and if you know how it work with Grid will be
very helpful.
Chetan |76.25.64.xxx |2009-07-16 09:52:28
Hey I just Realized It works with Grid.datasource Property as well.. Thanks
Man.. you are my life saver :cheer:
Sreejith  - Adding items to a listbox |144.36.249.xxx |2009-08-17 06:17:39
I was trying to add items to a listbox but this method does not help adding
objects to ListBox1.Items collection. Please suggest whats required.
Visveswaraiah  - Can do this |220.227.50.xxx |2009-08-18 01:26:34
I don't know direct method, but i used this code to do lot of actions in my
project indirectly, i will tell you how, see if it is useful for you.



1) Add a lable to the page "label1"

2) Add TextChanged event for lable as



private void label1_TextChanged(object sender, EventArgs e)

{

if (label1.Text != "")

listBox1.Items.Add(label1.Text);

}



3) Any way you know how to change value of label in threading, set value of
label as



label1.Text = "";

label1.Text = ;



Whenever you set value of lable as "" and Your Value and , it will call


label1_TextChanged event, that will add to list box.

Visveswaraiah  - re: Can do this |220.227.50.xxx |2009-08-18 01:28:37
Visveswaraiah wrote:
I don't know direct method, but i used this code to do lot of actions in my
project indirectly, i will tell you how, see if it is useful for you.



1) Add a lable to the page "label1"

2) Add TextChanged event for lable as



private void label1_TextChanged(object sender, EventArgs e)

{

if (label1.Text != "")

listBox1.Items.Add(label1.Text);

}



3) Any way you know how to change value of label in threading, set value of
label as



label1.Text = "";

label1.Text = YourValue;



Whenever you set value of lable as "" and YourValue, it will call

label1_TextChanged event, that will add YourValue to list box.

Visveswaraiah  - re: re: Can do this |220.227.50.xxx |2009-08-18 01:29:16
Visveswaraiah wrote:
[quote=Visveswaraiah]I don't know direct method, but i used this code to do lot
of actions in my project indirectly, i will tell you how, see if it is useful
for you.



1) Add a lable to the page "label1"

2) Add TextChanged event for lable as



private void label1_TextChanged(object sender, EventArgs e)

{

if (label1.Text != "" )

listBox1.Items.Add(label1.Text);

}



3) Any way you know how to change value of label in threading, set value of
label as



label1.Text = "";

label1.Text = YourValue;



Whenever you set value of lable as "" and YourValue, it will call

label1_TextChanged event, that will add YourValue to list box.

[/quote]
satish  - how to do with the function like form1.show() |220.225.238.xxx |2009-09-16 00:34:49
i have the same problem for the function
like form1.show()
wat to do with these
harshad  - too good but for method like progressBar1.PerformS |117.196.8.xxx |2010-01-17 03:45:52
thanks for this code now i face problem is method givwe me same error
progressBar1.PerformStep();
Hagen  - Usefull! |190.27.44.xxx |2010-01-21 15:39:08
Thank you, your solution gave me a hand when I was stucked. I'm using a
RichTextBox to show the progress of a serial protocol. I have a Delegate working
on receive messages from a class that controls the serial port; when I insert a
new text in the RTBx happened the exception.
Now, I'm trying to add new text, not erase the actual.

Best regards
Hagen, @HagenVoyager
COL
Murat  - Developer |94.54.17.xxx |2010-02-09 17:22:54
Not only very intelligent solution, but also very professional approach. Thank
you very much for this nice solution...
Hafeez  - re: Developer |202.172.7.xxx |2010-02-23 11:35:34
Good One.
Derek White |68.58.1.xxx |2010-03-13 21:23:51
http://javaflowswithin.blogspot.com/2010/03/c-thre adsafecontrol.html
Kamil |84.10.190.xxx |2010-06-16 10:26:23
thx ;]
Dan  - Programmer Analyst |206.54.145.xxx |2010-08-16 10:01:41
Nice solution. In my case, this was exactly what I was looking to implement in
a windows form copying a file over the network on a different thread than main.

Here is what I implemented combining your code with code from another link
entitled "Copy a file with progressbar in VB.NET "
http://khsw.blogspot.com/2005/08/copy-file-with-pr ogressbar-in-vbnet.html

Imports System.Threading
Imports System.Reflection

Public Class Form1


Private Delegate Function CopyProgressRoutine(ByVal totalFileSize As Int64,
ByVal totalBytesTransferred As Int64, _
ByVal streamSize As Int64, ByVal streamBytesTransferred As Int64, _
ByVal dwStreamNumber As Int32, ByVal dwCallbackReason As Int32, _
ByVal hSourceFile As Int32, ByVal hDestinationFile As Int32, _
ByVal lpData As Int32) As Int32

Private Declare Auto Function CopyFileEx Lib "kernel32.dll" (ByVal
lpExistingFileName As String, ByVal lpNewFileName As String, _
ByVal lpProgressRoutine As CopyProgressRoutine, ByVal lpData As Int32, _
ByVal lpBool As Int32, ByVal dwCopyFlags As Int32) As Int32

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles Button1.Click
Dim tr As New Thread(New ThreadStart(AddressOf copyMyFiles))
tr.Start()

End Sub

Sub copyMyFiles()
Dim cpr As New CopyProgressRoutine(AddressOf CopyProgress)
CopyFileEx("C:\FICSGP\MACROS\compl
ete\FICSGP_2010-08-10.MAC",
"\\ficsmailserv1\frs\macrostes
t\FICSGP_2010-08-10.MAC", cpr, 0, 0, 0)

End Sub

Private Function CopyProgress(ByVal totalFileSize As Int64, ByVal
totalBytesTransferred As Int64, ByVal streamSize As Int64, _
ByVal streamBytesTransferred As Int64, ByVal dwStreamNumber As Int32, _
ByVal dwCallbackR...
Last Updated on Sunday, 04 January 2009 00:24