Solved

Me.Invoke doesnt work from within a class instance

Posted on 2008-09-29
11
508 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
 
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
3 Use Cases for Connected Systems

Our Dev teams are like yours. They’re continually cranking out code for new features/bugs fixes, testing, deploying, testing some more, responding to production monitoring events and more. It’s complex. So, we thought you’d like to see what’s working for us.

 
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

For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
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…

920 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now