Link to home
Start Free TrialLog in
Avatar of tfsln
tfslnFlag for New Zealand

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

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of johnaryan
johnaryan
Flag of Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tfsln

ASKER

Im a VB developer, im not sure if i can use the lock. It seems to be similar to the Sync Lock statement.

I dont have an answer to my first question, and i still have confusion about the second one...
Avatar of Mike Tomlinson
"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.Timer'.
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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

Open in new window

Avatar of tfsln

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?
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
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of tfsln

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?