I have an app that needs to fire off a couple of events at certain times during the day - the times are all defined by the users. I can think of a couple of ways of doing it but none of them sit too well. The timing doesn't have to be of a particularly high resolution - a minute or so each way is fine.
My ideas :
When the app starts up read all the times and start timers off that will Tick at the appropriate time
Start a timer off that'll check every minute or so for 'current events'
tia for any better solutions.
Store/index the events sorted by when they next need attention. This could be in memory or not according to how many there are, how often you make changes, etc. If all of your events fire once a day, this list is basically a circular buffer which only changes when users change their events.
Start a timer which will 'tick' at the time of the event at the head of the list. Round up to the next minute if you like.
When the timer fires, process all events which are now in the past [edit - and which haven't already been processed], re-insert them into the list if necessary (i.e. if you don't have the "circular buffer" optimisation), and set a new timer.
Obviously, when you change the set of events, or change the time for an existing event, then you may need to reset the timer to make it fire earlier. There's usually no point resetting it to fire later - you may as well just let it go off and do nothing. And if you put an upper limit of one minute on how long the timer can run (or just have a 1 minute recurring timer), then you can get within 1-minute accuracy without ever resetting. This is basically your option 2.
Arguably you should use an existing framework rather than rolling your own, but I don't know C# so I have no idea what's available. I'm generally a bit wary of the idea of setting squillions of timers, because some environments don't support that (or don't support it well). Hence this scheme, which requires only one. I don't know whether C# has any problems in that respect, but this scheme can easily be arranged to use O(1) RAM if necessary, which can't be beat.
Have a look at Quartz.Net. It is a scheduler framework (originally for Java).
This sounds like a classic case for a Windows Service. I think there is a Windows Service project type in VS2005/2008. The service coupled with a simple database and a front-end application to allow users to set the trigger times would be all you need.
If it won't change very often, Scheduled Tasks is also an option.
I've written a few programs along these lines.
I suggest #2. All you need to to is keep a list of times that events are "due" at, and every X amount of time (depending on your resolution) check your list for "now" events. You can pick up some optimization if you can guarantee the list is sorted, and that each event on the list is due exactly once. Otherwise, if you have recurring events, you have to make sure you cover your window. What I mean is, if you have an event that is due at 11:30 am, and you're checking every seconds, then it's possible that you could check at 11:29:59, and then not again until 11:31:01, due to the inprecision of the CPU time-slices. So you'll need to be sure that one of those checks (11:29 or 11:31) still picks up the 11:30 hit, and that ONLY one of them does (i.e., you don't run at both 11:29 and 11:31).
The advantage this approach has over checking only on times you know to be on your list is that allows your list to be modified by 3rd parties without your knowledge, and your event handler will continue to 'just work'.
The simplest way would likely be to use Windows scheduler.
Otherwise you need to use one of the Timer classes, calculating how long until the first event. This approach, unlike the scheduler, allows new events to be found by the running process (and, possibly, resetting the timer).
The problem with #1 is that the number of milliseconds before an event may be too large to store in the Timer's interval, and as the number of events increase, your number of timers could get unweildly.
I dont see anything wrong with #2, but I would opt for a background worker or a thread.
Related
I'm pretty new to profiling so I don't know how to even approach this issue. Basically, I want to discover why some hiccups in the UI are occurring. Profiler seems to be made for solving these kinds of issues so I went with that. I'm using Visual Studio 2010 on a Windows 8 machine so my only option is instrumentation profiling.
Unfortunately, what I get is a bunch of distracting hot paths that occur because of MessageBox.Show calls and long-running threads waiting for data with Monitor.Wait. These methods, of course, take orders of magnitude longer than the issues I'm trying to understand.
Is there no way to somehow filter-out these long-running methods? Ideally by function name or some other criteria, perhaps elapsed exclusive time.
Profiling is not for UI. Profiling is for calculations and other logic. If you really need to profile UI (which you should not) you can hide message boxes and simulate button clicks. Something like:
#if PROFILE_VERSION
DialogResult result = DialogResult.OK;
#else
DialogResult result = MessageBox.Show();
#endif
Of course you'll need to define PROFILE_VERSION and create new configuration for this.
But really, you should only test your logic.
Aside from hot paths being some of the pointless information profilers give you, here is how I would approach finding your "hiccups".
Most of the time I use random pausing.
I try to collect samples during the slow times (the "hiccups") so I can see what it's doing in that time.
If I get samples that I can see are not relevant, I just ignore those.
If the hiccups happen too fast to do that, there's a more difficult method.
It requires setting a few-millisecond timer interrupt with a handler.
When the suspect code starts, it enables the timer, and when it finishes it disables the timer.
That way, if it takes longer than normal to finish, the timer goes off. If I set a breakpoint in the handler, I can look to see what the program was doing when the timer went off.
That's a way to get a sample.
If I get several samples, that's usually enough to show the problem.
Forgive me for this question, but I can't seem to find a good source of when to use which. Would be happy if you can explain it in simple terms.
Furthermore, I am facing this dilemma:
See, I am coding a simple application. I want it to show the elapsed time (hh:mm:ss format or something). But also, to be able to "speed up" or "slow down" its time intervals (i.e. speed up so that a minute in real time equals an hour in the app).
For example, in Youtube videos (* let's not consider the fact that we can jump to specific parts of the vid *), we see the actual time spent in watching that video on the bottom left corner of the screen, but through navigating in the options menu, we are able to speed the video up or down.
And we can actually see that the time gets updated in a manner that agrees with the speed factor (like, if you choose twice the speed, the timer below gets updated twice faster than normal), and you can change this speed rate whenever you want.
This is what I'm kinda after. Something like how Youtube videos measure the time elapsed and the fact that they can change the time intervals. So, which of the two do you think I should choose? Timer or StopWatch?
I'm just coding a Windows Form Application, by the way. I'm simulating something and I want the user to be able to speed up whenever he or she wishes to. Simple as this may be, I wish to implement a proper approach.
As far as I know the main differences are:
Timer
Timer is just a simple scheduler that runs some operation/method once in a while
It executes method in a separate thread. This prevents blocking of the main thread
Timer is good when we need to execute some task in certain time interval without blocking anything.
Stopwatch
Stopwatch by default runs on the same thread
It counts time and returns TimeSpan struct that can be useful in case when we need some additional information
Stopwatch is good when we need to watch the time and get some additional information about how much elapsed processor ticks does the method take etc.
This has already been covered in a number of other questions including
here. Basically, you can either have Stopwatch with a Speed factor then the result is your "elapsed time". A more complicated approach is to implement Timer and changing the Interval property.
I have an application and I have 6 timers. each timer have different interval which mean 1s, 1s, 3s, 3s, 3s, 3s, respectively. Require CPU is always 2% to 3%.
in my PC is fine due to my PC's capability.
I am sure it may cause application if PC's capability is low.
Is there any effective way to use timer? or other running background?
The reason, I use timer because this timer will query database(get total amount) whenever user added or edit or delete product record, not just product record any record.
Timer 1s is for show Date and Time label
Timer 1s is to interact with datagriview, update the whole column
and Other timers is to get data from MySql Server. As my estimation, the max num of records can be 10 records.
Thanks
It's unclear why you think you need multiple timers here, and you don't even say which timer implementation you are using - and it would likely make a difference.
Employing a single timer that triggers on a reasonable minimal precision (1s, 100ms, etc) would reduce the overall overhead and would likely serve your purpose better. Of course that's said without any indication of what your actually trying to achieve.
It sounds as if you may have multiple issues, but to answer your question, running multiple timers will no cause your application to crash. How you implement the timers and if you are locking the code blocks that are called when a time is fired are important. If you are allowing code blocks to be executed before the code block has finished executing a previous call it can cause your application to become unstable. You should look at timers and perhaps even threads. Without knowing more about what you are doing it is difficult to provide a an more definitive answer to your question.
I was wondering if its possible to check how frequently, in terms of an accurate timespan, a certain method gets executed in C#?
For example I have a device (a microphone), and once I start the microphone, its StartCollectingSamples event is fired which will in turn start invoking the Microphone_CollectSampleData() method.
How can I check how frequently this event is being raised? I place a breakpoint on Microphone_CollectSampleData() and it seems to get executed very frequently, possible 2/3 times a second, but how can I get that accurate time value?
Depending on the version of the visual studio you got, you can use the provided profiler, to analyze how many time each method is executed, how long it runs, etc.
There are other, non microsoft products, which aim to do the same, such as antz profiler, but they usually cost money after a trial period.
We implemented a windows service that has a couple of timers in it. Over time the logic for the timers got more and more complicated. Its time to refactor our solution and one possible way would be to use a well documented framework that handles our requirements.
There are rules like:
start timer A each day at 9am
start timer B each 2min
if timer A is started dont start any other timer
timer C and D are not allowed to run at the same time
I looked at Quartz.net because it had the first 2 requirements of our list, but it doesnt handle any concurrency rules.
Is there any framework I could have a look at?
I had similar requirements: essentially what you need is a state machine that can be easily serialized to disk or a database, some way to specify the state machine easily using hierarchical states, some way to easily specify temporal events (After, Every, At) and some way to easily know when to load the state machine back into memory to advance state based on the current time.
In the end I wrote my own state machine as I didn't find one that met my requirements, in particular the temporal events and the serialization requirements. You can get the source code in a Nuget Package. Blog entry here. Feedback welcome.