|
-
May 27th, 2012, 05:45 AM
#1
Thread Starter
Fanatic Member
[RESOLVED] Cross-thread operation not valid in Worker?
hi,
I'm getting a Cross-thread operation not valid error when my label text changes - this is very strange because it was working up until yesterday 
The only way I can get this to work is by applying the invoke
Code:
Me.Invoke(Sub()
Me.lbl1.Text = "Editing file"
End Sub)
Is there a more simpler solution or will I have to invoke all my label coding?
Please mark threads as resolved once the problem has been solved.
I apprecaite all your help/advice given 
-
May 27th, 2012, 07:10 AM
#2
Re: Cross-thread operation not valid in Worker?
It's not strange at all. You should never be trying to access a control directly from any thread other than the UI thread. If you're using a BackgroundWorker, as it appears you are, then it has a mechanism built in to allow you to do that. To learn how to use it, follow the CodeBank link in my signature and check out my thread on Using The BackgroundWorker.
-
May 27th, 2012, 09:22 AM
#3
Thread Starter
Fanatic Member
Re: Cross-thread operation not valid in Worker?
Thanks Jmcilhinney, I will save the thread you created as a favourite 
So I'm trying to implement it into my program and struggling a little bit.
The current coding I have is.
Code:
' BG Worker Do Work
'code
Me.lbl1.Text = "One Done"
'code
Me.lbl1.Text = "Two Done"
'code
Me.lbl1.Text = "Three Done"
'code
Me.lbl1.Text = "Four Done"
'code
Me.lbl1.Text = "Five Done"
' BG Worker Work Completed
Me.lbl1.Text = "Completed"
So would I need to add something like the following
Code:
'do work
Dim labeltext As String
e.Result = labeltext
' work completed
Dim labeltext As String() = DirectCast(e.Result, String())
Me.lbl1.Items.AddRange(labeltext)
Please mark threads as resolved once the problem has been solved.
I apprecaite all your help/advice given 
-
May 27th, 2012, 09:27 AM
#4
Re: Cross-thread operation not valid in Worker?
The very first post in that CodeBank thread contains a code example that updates a Label repeatedly during the background operation and then again when it's finished. All you have to do is follow that example.
-
May 27th, 2012, 09:48 AM
#5
Thread Starter
Fanatic Member
Re: Cross-thread operation not valid in Worker?
Jmcilhinney, thanks.
I might be mistaken but your example is more like a percentage am I correct? Ie it shows the progress when 0-100%% complete? however my requirements are slightly different as I would only want to display the label once the current coding is started/or is cancelled?
So something like
Code:
'do work event
If Not worker.CancellationPending Then
Me.lbl1.Text = "Run coding 1"
' code
If worker.CancellationPending Then
e.Cancel = True
Me.lbl1.Text = "Cancelling coding 1"
Exit Sub
End If
End If
So would I still follow the same principle?
Please mark threads as resolved once the problem has been solved.
I apprecaite all your help/advice given 
-
May 27th, 2012, 09:56 AM
#6
Re: Cross-thread operation not valid in Worker?
Who cares what it shows? A String is a String. Have you actually read the example?
Code:
'This method is executed in a worker thread.
Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, _
ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker)
For i As Integer = 1 To 100
'Raise the ProgressChanged event in the UI thread.
worker.ReportProgress(i, i & " iterations complete")
'Perform some time-consuming operation here.
Threading.Thread.Sleep(250)
Next i
End Sub
'This method is executed in the UI thread.
Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, _
ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Me.ProgressBar1.Value = e.ProgressPercentage
Me.Label1.Text = TryCast(e.UserState, String)
End Sub
As I have already stated, you call ReportProgress and pass the String as the second argument. You handle ProgressChanged, get the String back and display it in the Label.
-
May 27th, 2012, 06:23 PM
#7
Thread Starter
Fanatic Member
Re: Cross-thread operation not valid in Worker?
Thanks mate, solved it now.
Please mark threads as resolved once the problem has been solved.
I apprecaite all your help/advice given 
-
May 28th, 2012, 03:58 AM
#8
Re: [RESOLVED] Cross-thread operation not valid in Worker?
Actually you should never try to access any Control inside the DoWork.
There are just two ways you would need them inside the DoWork event.
- You want to pick up some value from some control.
- You want to update some control's value.
To pick some value from any control, put such values in variables, so that you don't need to reference the controls from inside the DoWork event. Do that before you call the RunWorkerAsync method (which in turn fires the DoWork event).
If you want to set something in any control, you should use the ReportProgress method to pass your values out of BackgroundWorker. The values you pass from ReportProgress can be accessed from the ProgressChanged event. You can assign those values to your controls or do anything else you want to do with them.
So you do:
Code:
' Inside DoWork event
worker.ReportProgress(10, "Run coding 1")
' In ProgressChanged event
Me.lbl1.Text = CType(e.UserState, String)
This was just a simple example where a string is passed.
But in many cases you may want to pass more information than this to the ProgressChanged event.
e.g. you have 10 labels, and you also want to pass which label's text property to set, along with the string value you want to set.
Fortunately, the ReportProgress can pass a value of type Object to the ProgressChanged event. This means that you can pass virtually anything via that method. It can be as small as a string or number, or it can be a complex structure like some class object or array etc.
Below is an example where I pass the control name and its value to set.
1. Create a structure/class which can hold the control name (name of label) and the text value to set.
Code:
Public Structure ControlWithText
Public ControlName As Control
Public Text As String
Public Sub New(ByVal ctrl As Control, ByVal text As String)
Me.ControlName = ctrl
Me.Text = text
End Sub
End Structure
2. From inside the DoWork event, you pass an object instance of this structure.
e.g.
Code:
worker.ReportProgress(10, New ControlWithText(Label1, "Run coding 1"))
worker.ReportProgress(20, New ControlWithText(Label2, "Run coding 2"))
3. Now in your ProgressChanged event, you will have this object available. Just get the control name and the text out of it and do your task appropriately.
Code:
If TypeOf e.UserState Is ControlWithText Then
Dim cwt As ControlWithText = CType(e.UserState, ControlWithText)
cwt.ControlName.Text = cwt.Text
End If
Last edited by Pradeep1210; May 28th, 2012 at 04:03 AM.
-
May 29th, 2012, 02:29 AM
#9
Thread Starter
Fanatic Member
-
May 30th, 2012, 07:25 AM
#10
Re: [RESOLVED] Cross-thread operation not valid in Worker?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|