tfsln
asked on
Me.Invoke doesnt work from within a class instance
I create a background worker from within my class, and in that background worker i want to disable a timer.
I have 2 questions...
1) How can i invoke a delegate method, as i could from a form instance by using Me.Invoke? The Tmr.Enable isnt thread safe is it? Because it lies on a different thread.Do i need to invoke a method on the main thread to perform a thread safe call?
2) I have a TestVariable delcared as public within the module. Is it safe to read/write this variable from different threads within the class? Is there anything i need to be aware of?
I have 2 questions...
1) How can i invoke a delegate method, as i could from a form instance by using Me.Invoke? The Tmr.Enable isnt thread safe is it? Because it lies on a different thread.Do i need to invoke a method on the main thread to perform a thread safe call?
2) I have a TestVariable delcared as public within the module. Is it safe to read/write this variable from different threads within the class? Is there anything i need to be aware of?
Public Class TestClass
Public TestVariable As String
Private WithEvents Tmr As System.Windows.Forms.Timer
Private WithEvents Bw As System.ComponentModel.BackgroundWorker
Public Sub New()
Tmr = New System.Windows.Forms.Timer
Bw = New System.ComponentModel.BackgroundWorker
Tmr.Interval = 5000
Tmr.Enabled = True
End Sub
Private Sub Tmr_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles Tmr.Tick
If Bw.IsBusy = False Then Bw.RunWorkerAsync()
End Sub
Private Sub Bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Bw.DoWork
If thiscondition = True Then
Tmr.Enabled = False
End If
End Sub
End Class
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
"Tmr.Enable" is thread safe because System.Windows.Forms.Timer isn't a visible control. The Invoke()/InvokeRequired() concept doesn't apply to it...
This is evidenced by the error you receive when you use InvokeRequired() with it:
'InvokeRequired' is not a member of 'System.Windows.Forms.Time r'.
This is evidenced by the error you receive when you use InvokeRequired() with it:
'InvokeRequired' is not a member of 'System.Windows.Forms.Time
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
sorry for the double post, I forgot to add something. The background Worker also has a completed event. Instead of looping a timer to see if it is working, why not just handle the completed event and rerun the background worker.
Public Class Class1
Public TestVariable As String
Private _someCondition As Boolean
Private WithEvents Bw As System.ComponentModel.BackgroundWorker
Public Sub New()
Bw = New System.ComponentModel.BackgroundWorker
Bw.WorkerReportsProgress = True
End Sub
Private Sub Bw_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles Bw.DoWork
'Do stuff
'Set _someCondition value for rerun
End Sub
Private Sub Bw_Complete(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles Bw.RunWorkerCompleted
If _someCondition Then
Bw.RunWorkerAsync()
End If
End Sub
End Class
ASKER
bhmahler; Cheers for the timer code, ill use that. As for the background worker, well that would be convenient, but unfortunately the timer is necessary.
Idle_Mind: Thanks for that. Does this mean that any control or object which does not have an InvokeRequired property can be safely called from other threads? This would obviously include variables in the class/module right?
Idle_Mind: Thanks for that. Does this mean that any control or object which does not have an InvokeRequired property can be safely called from other threads? This would obviously include variables in the class/module right?
Yes you can access class level variables from within a thread. Most all are thread safe. You get into cross threading issues mostly when you try to access elements on the UI thread from a background thread. If you do not need to edit anything on the UI thread, you will most likely never need to use invoke.
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Cool, so just to help my understanding of this...
1) What happens if multiple threads attempt to modify a class member at the same time? i.e. just a public variable in the class?
2) When a function is executed by multiple threads simultaneously, it is my understanding that each function runs in a seperate memory space so that the local variables inside that function do not conflict is this correct?
1) What happens if multiple threads attempt to modify a class member at the same time? i.e. just a public variable in the class?
2) When a function is executed by multiple threads simultaneously, it is my understanding that each function runs in a seperate memory space so that the local variables inside that function do not conflict is this correct?
ASKER
I dont have an answer to my first question, and i still have confusion about the second one...