|
-
Nov 21st, 2009, 08:34 AM
#1
Thread Starter
Lively Member
[RESOLVED] How to use SynchronizingObject property
I have 5 windows services that each uses 2 or more system.timers.timer. I want to use SynchronizingObject property to eliminate thread pooling issuse! Can someone please show me how to use this?
Thank you!
/Patrik
This is a example of one of my timers:
Private Timer As New System.Timers.Timer
AddHandler Timer.Elapsed, New System.Timers.ElapsedEventHandler(AddressOf Me.Timer_Elapsed)
Timer.Interval = 8000
Timer.AutoReset = False
Timer.Enabled = True
Private Sub Timer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs)
Timer.Enabled = False
' do my code here
Timer.Enabled = true
ENS SUB
-
Nov 21st, 2009, 09:52 AM
#2
Re: How to use SynchronizingObject property
There's really nothing to "using" the SynchronizingObject property. You simply assign an appropriate object to the property and then the Timer will raise its events on the thread that "owns" that object rather than on an arbitrary thread pool thread.
The thing is, the SynchronizingObject property is type ISynchronizeInvoke and there aren't many types that implement that interface that you can create an instance of to assign to the property. In fact, the only class that I'm aware of that does implement the ISynchronizeInvoke is Control. Normally, the SynchronizingObject property is used in a WinForms app and you simply assign the form the Timer "belongs to" to its SynchronizingObject property. In fact, if you add the Timer in the designer then that will be done automatically. As your app is a Windows service, there are no forms or controls at all, so you have nothing ready-made to assign to the SynchronizingObject property.
Now, you could define your own class that implements ISynchronizeInvoke, which you would probably do using the SynchronizingContext class. Before we get into that though, exactly what throead pooling issues are you talking about? I'm guessing that all you need is to employ some standard thread synchronisation techniques, e.g. SyncLock, and you'll be fine.
-
Nov 21st, 2009, 01:30 PM
#3
Thread Starter
Lively Member
Re: How to use SynchronizingObject property
Thank you for your reply! It makes sence what you are saying!
Well i try to explain the problem that occurs occationally.
I several watched folders, that i watch for pdf:s. Occationally 1 PDF:s filename in folder A is replaced by a PDF:s filename that has come at the same time in folder B. The file is right, but the filename is replaced.
I can't think of anything else that it has something to do with threading.. I have 9 timers in 5 win services!
I would be grateful if you could show me how i implement ISynchronizeInvoke or synclock that you suggested!
Thank you!
/Patrik
-
Nov 21st, 2009, 07:51 PM
#4
Re: How to use SynchronizingObject property
If you find that two threads are interfering with each other by one modifying data that another is using, the first thing to consider is using a SyncLock statement, e.g.
vb.net Code:
Private syncRoot As New Object Private Sub SomeMethod() SyncLock syncRoot 'blah, blah blah End SyncLock End Sub
Now only one thread will be able to do blah, blah, blah at a time. Once a thread enters the SyncLock block, no other thread will be able to enter until the first thread leaves. You can also create multiple SyncLock blocks that lock on the same object, i.e. syncRoot, and then they will be linked, i.e. only one thread will be able to enter any of them at a time.
-
Nov 22nd, 2009, 05:02 AM
#5
Thread Starter
Lively Member
Re: How to use SynchronizingObject property
Thank you!
So can i use SyncLock like this?
Private Sub Timer_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs)
SyncLock syncRoot
Timer.Enabled = False
' do my code here
Timer.Enabled = true
End SyncLock
END SUB
-
Nov 22nd, 2009, 05:46 AM
#6
Re: How to use SynchronizingObject property
You don't need to set the Enabled property like that. By default a Timers.Timer only raises its Elapsed event once anyway. You would have had to have set the AutoReset property to True to get it to raise more than one. Why not just leave the AutoReset property as False and then only one event will be raised? You can then just call Start at the end of the event handler.
-
Nov 22nd, 2009, 06:21 AM
#7
Thread Starter
Lively Member
Re: How to use SynchronizingObject property
I stop the timer beacause it can take up to 3 minutes to run the code and when the code has run it starts the timer again, because timer interval is 8 sec.. So i must be sure that the code has finished before the next interval!
So does my code work like this or should i change something?
/Patrik
-
Nov 22nd, 2009, 07:08 AM
#8
Re: How to use SynchronizingObject property
OK, so I take it that it doesn't always take that long then.
-
Nov 22nd, 2009, 08:17 AM
#9
Thread Starter
Lively Member
Re: How to use SynchronizingObject property
No, it's very seldom it takes that long, usually it takes about 4 secs to process the file, but sometimes it takes several minutes..
So i can use that code i posted earlier then?
Thank you for your help!
/Patrik
-
Nov 22nd, 2009, 08:23 AM
#10
Re: How to use SynchronizingObject property
You can, but the problem you have is that, if it takes a long time to process data in the Elapsed event handler of one Timer, the other Timer might be piling up threads at the SyncLock in the mean time. You should probably stop the Timer before the SyncLock, so no Timer will ever have multiple event handlers pending.
-
Nov 22nd, 2009, 08:58 AM
#11
Thread Starter
Lively Member
Re: How to use SynchronizingObject property
-
Nov 26th, 2013, 10:10 AM
#12
Member
Re: [RESOLVED] How to use SynchronizingObject property
Is there a way to assure that a Timer and an OleDbConnection share the same thread? Might this SynchronizingObject property be used for that?
VBobCat
VS2013 & Office-VBA
Autodidact, part-time programmer for job needs
-
Nov 26th, 2013, 08:34 PM
#13
Re: [RESOLVED] How to use SynchronizingObject property
 Originally Posted by VBobCat
Is there a way to assure that a Timer and an OleDbConnection share the same thread? Might this SynchronizingObject property be used for that?
Neither Timers nor OleDbConnections have threads so how can they share one? The only time that it really makes sense to talk about a relationship between an object and a thread is for controls. That's because the handle of the control can only be accessed on the thread on which it was created. For any other type of object, there is no specific relationship between it and a thread. In the case of a a Timers.Timer, it raises its Elapsed event on a ThreadPool thread but the Timer itself doesn't exist on any specific thread. If you set the SynchronizingObject property then you will be assigning a form or other control to it. The handle of that control is used to ensure that the Elapsed event is raised on the thread that created that handle, i.e. the UI thread.
In the case of an OleDbConnection, there's no thread affinity at all. You can call Open on a specific thread but that makes no difference. The connection is either open or not, regardless of which thread it was opened on. You can then execute commands over that connection on whatever thread you like.
It would be possible to use the SynchronizationContext class to determine what thread an Elapsed event was raised on and execute other methods on that thread later. The thing is, the Elapsed event can be raised on any ThreadPool thread each time, not necessarily the same one. Also, there's no guarantee that a ThreadPool thread will exist at a later stage, so trying to execute a method on the same thread that an Elapsed event was previously raised on may not be safe.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|