Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Me.Invoke doesnt work from within a class instance

Posted on 2008-09-29
11
510 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
Master Your Team's Linux and Cloud Stack

Come see why top tech companies like Mailchimp and Media Temple use Linux Academy to build their employee training programs.

 
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

MIM Survival Guide for Service Desk Managers

Major incidents can send mastered service desk processes into disorder. Systems and tools produce the data needed to resolve these incidents, but your challenge is getting that information to the right people fast. Check out the Survival Guide and begin bringing order to chaos.

Question has a verified solution.

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

Suggested Solutions

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
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 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…
In an interesting question (https://www.experts-exchange.com/questions/29008360/) here at Experts Exchange, a member asked how to split a single image into multiple images. The primary usage for this is to place many photographs on a flatbed scanner…

809 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