Solved

Me.Invoke doesnt work from within a class instance

Posted on 2008-09-29
11
509 Views
Last Modified: 2013-12-04
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

0
Comment
Question by:tfsln
  • 3
  • 3
  • 2
  • +1
11 Comments
 
LVL 5

Accepted Solution

by:
johnaryan earned 168 total points
ID: 22601039
you should look into the lock keyword, it helps to avoid race conditions

String s = "string1";
lock(s)
{
// do operations on object and no other thread can access it.
s = "string2";
}

good reference: http://msdn.microsoft.com/en-us/library/c5kehkcz(VS.71).aspx
0
 

Author Comment

by:tfsln
ID: 22601071
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...
0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 22601138
"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'.
0
DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

 
LVL 8

Assisted Solution

by:bhmahler
bhmahler earned 166 total points
ID: 22604953
You should be using a Timers.Timer within a class not a forms.Timer.
    Private WithEvents tmr As Timers.Timer
 
    Private Sub tmr_elapsed(ByVal sender As Object, ByVal e As Timers.ElapsedEventArgs) Handles tmr.Elapsed
 
    End Sub

Open in new window

0
 
LVL 8

Expert Comment

by:bhmahler
ID: 22604983
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

0
 

Author Comment

by:tfsln
ID: 22609137
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?
0
 
LVL 8

Expert Comment

by:bhmahler
ID: 22609188
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.
0
 
LVL 85

Assisted Solution

by:Mike Tomlinson
Mike Tomlinson earned 166 total points
ID: 22609201
Yes it does...unless you have a specific "atomic" operation that needs to be completed.  This would be a series of actions that all have to be done together without being interrupted.

You do not need to worry about this type of thing unless you have MULTIPLE threads trying to do the series of actions at possibly the same time.  Then you would use SyncLock (or another thread synchronization method) as johnaryan suggested earlier.
0
 

Author Comment

by:tfsln
ID: 22609241
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?
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

After several hours of googling I could not gather any information on this topic. There are several ways of controlling the USB port connected to any storage device. The best example of that is by changing the registry value of "HKEY_LOCAL_MACHINE\S…
The ECB site provides FX rates for major currencies since its inception in 1999 in the form of an XML feed. The files have the following format (reducted for brevity) (CODE) There are three files available HERE (http://www.ecb.europa.eu/stats/exch…
This Micro Tutorial will give you a basic overview how to record your screen with Microsoft Expression Encoder. This program is still free and open for the public to download. This will be demonstrated using Microsoft Expression Encoder 4.
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…

785 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question