System.Timers.Timer not firing at the interval set - c#

I am working in timer from System.Timers namespace in wpf application.I want some backend behaviour to execute with timers and call in n milliseconds.
Timer sampleTimer = new Timer();
sampleTimer.Elapsed += (sender, e) => CallElapsedEvent();
sampleTimer.Interval = 10000; //called every 10 seconds
sampleTimer.Enabled = true;
public void CallElapsedEvent(){
Console.WriteLine(DateTime.Now + " - CallElapsedEvent called");
}
Here is the output of the code
16:45:09 - CallElapsedEvent called
16:45:32 - CallElapsedEvent called
16:45:32 - CallElapsedEvent called
Expected behaviour is that after 9th second , it must fire again at 19.But it is called after an interval of 23 seconds and that too twice(at exactly the same sec).This is happening occassionally and causes some unexpected exception.Why is that happening so?
From what I read about ,it allocates thread pool thread every n interval seconds.If elapsed event is not finished it allocates some other new thread.So, in my case is there are no other free worker threads available at 19th second and waits for the thread.
Why is that happening so and is there any way to enter only one thread to fire at a time?

Related

scheduling a windows service without using the task scheduler

I have a windows service that archives files from a paticular folder. I want the program to run everday at a specific time. I can do that using the task scheduler. what I want to do is to schedule the task without actually assessing the windows task scheduler GUI. Maybe a batch script that schedules the program to run every day even when the system is on sleep or maybe something else i can do?
does anyone have an idea of how this thing can be implemented?
The solution is pretty basic . so the thing is that instead of using the task scheduler we are creating a scheduler itself in our code so there is a thread that will be created that will always be checking for the time that I want my actual code to run and once the current time is the time that I want the method to run it will trigger the main program(in the example the method I want to trigger is named ArchiveFile) .
so first in the OnStart I am setting a new timer and want it to fire 24x7,every hour.
then in the timer_elapse i want to check if the current time is the time I want my method to execute and if true it will call the method that I want to execute.(in this example I have set the time to be 9 pm or 21 hours)
protected override void OnStart(string[] args)
{
timer = new System.Timers.Timer();
timer.Interval = 36000; // that fires every hour
timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed); //calling the elapse event when the timer elapses
timer.AutoReset = true; // AutoReset is set to true as we want the timer to fire 24x7 so that the elapse event is executed only at the requried time
timer.Enabled = true;
}
protected void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) //everytime the elapse event occurs the TimeCheck method will be called
{
TimeCheck();
}
public void TimeCheck() //method to check if the current time is the time we want the archiving to occur
{
var dt = DateTime.Now.Hour;
if(dt==21)
{
Archivefile();
}
}

Scheduling in Rx .NET

Expected all be executed on the main thread of .NET Core 2.0 console app, so the output being blocked for 10 seconds:
static void Main(string[] args)
{
WriteLine($"We are on {Thread.CurrentThread.ManagedThreadId}");
var subject = new Subject<long>();
var subscription = subject.Subscribe(
i => WriteLine($"tick on {Thread.CurrentThread.ManagedThreadId}"));
var timer = Observable.Interval(TimeSpan.FromSeconds(1))
.SubscribeOn(Scheduler.CurrentThread)
.Subscribe(i => subject.OnNext(i));
Thread.Sleep(10000);
}
Not the case though – a new line comes to console every other second being dispatched by random threads:
We are on 1
tick on 4
tick on 5
tick on 4
tick on 4
tick on 4
tick on 4
tick on 4
tick on 4
tick on 5
What did I do wrong?
The Scheduler.CurrentThread / CurrentThreadScheduler will queue items on the same thread that made call to schedule, which will be the thread that the timer happens to run on. Calling Scheduler.CurrentThread does not pin the execution of items scheduled via it to the thread that you make the call to Scheduler.CurrentThread on but rather the thread that calls .Schedule().
Also, you call SubscribeOn() which only affects the thread where the .Subscribe() call is going to be made. If you want to control the execution of the item processing, you rather want to call .ObserveOn().
If you want everything to run on the main thread, I suggest running the timer on the main thread, by specifying a scheduler on the interval observable:
Observable.Interval(TimeSpan.FromSeconds(1), Scheduler.CurrentThread)

Threading and timers inside an emulator

I'm developing a Chip-8 emulator in C#, I have completed partially almost every aspect but there is something I'm still wondering about speed control of the emulator.
What I'm doing now is assuming that I get 60 frames per second, I use a timer that fires 1/60 seconds in the following manner (pseudocode):
timer_ticked()
{
for(int i = 0; i < Settings.CyclesPerFrame; i++)
{
EmulateCycle();
}
if (IsDrawFlagSet)
{
DrawGraphics();
}
}
I'm using a high resolution timer called microtimer http://www.codeproject.com/Articles/98346/Microsecond-and-Millisecond-NET-Timer , I believe that the timer doesn't wait for timer_ticked to finish to fire the next cycle (fon instance, creating a new thread) and I'm having an issue with threads and the form since trying to paint to a window with GDI (using the control.GetGraphics() method) seems to be threadsafe, but trying to create an SDLDotNet approach (just an example) doesnt.
Which approach do you think is best to control the speed of an emulator without getting into timer thread insanity?
PS: You can find the source code of the emulator in GitHub: https://github.com/AlFranco/C8POC
Thank you!
If you tick method is being called again before it's done, the problem isn't with your timer. It's because the processing is taking longer than that 16.6 ms. Getting a better timer isn't going to solve your problem.
That said, you can prevent reentrancy in a couple of ways.
You could just disable the timer when you enter the callback, and re-enable it when you're done. That'll prevent multiple invocations:
timer_ticked()
{
timer.Enabled = false;
// do stuff here
timer.Enabled = true;
}
Note that this doesn't give you a perfect 16.6 ms tick frequency. Rather, the next tick will occur 16.6 ms (approximately) after you enable the timer. Your real period is 16.6 ms plus however long it takes to do the processing.
The only time this would fail is if the timer_ticked method wasn't called before the next tick happened.
If you want to guarantee that you can't get concurrent ticks, you can use a System.Threading.Timer and set it up as a one-shot (no periodic signaling). For example:
Timer myTimer = new Timer(timer_tick, null, 16, -1);
The -1 in the last parameter tells it not to be a periodic timer. It'll fire once and stop.
Then, in your timer tick:
timer_tick()
{
// do stuff
// restart the timer
myTimer.Change(16, -1);
}
Edit
You can't easily tell the timer not to issue a tick if the handler is still processing the previous tick. You can, however, prevent the timer tick handler from doing anything on that subsequent tick. You simply use a Monitor:
private object timerLock = new object();
timer_ticked()
{
if (!Monitor.TryEnter(timerLock))
return;
try
{
// do stuff here
}
finally
{
Monitor.Exit(timerLock);
}
}
The problem with such a solution is that if your timer is set of 16 ms and the handler takes 17 ms, then your effective update rate will be once every 32 ms, because the second tick is essentially ignored. You're better off with the one-shot timer deal.
Another possibility is to use a Stopwatch to time how long your handler takes, and subtract that from the next delay period:
timer_ticked()
{
var sw = Stopwatch.StartNew();
// do stuff
timer.Change(16-sw.ElapsedMilliseconds, -1);
}
But it's not quite that simple. If it takes longer than 16 ms for the handler to do its thing, you'll end up with a negative delay. So you'll want:
var delayTime = Math.Max(0, 16 - sw.ElapsedMilliseconds);
timer.Change(delayTime, -1);
But again, if your handler regularly takes longer than the timer delay, then this isn't going to help you. You'll either have to reduce your timer frequency (i.e. make a longer delay) or optimize your processing code.

How to make async pause in C#?

I have a program written in C# (Visual Studio), that works on a tray.
I want it to do one action every 10 minutes.
I have following code now:
while(true)
{
Thread.Sleep(10000);
// my stuff
}
But it doesn't work. It freezes a program.
You should use the timer object and not create a while loop.
System.Timers.Timer _timer = new System.Timers.Timer();
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
//30 seconds
_timer.Interval = 30000;
_timer.Start();
private void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
//do your logic
}
Thread.Sleep makes the calling thead Sleep for an X ammount of time. If this thread is the frontend thread (the one responsible for handling messages), it will indeed freeze the application since any message for handling events or repainting wont be handeled untill the Thread wakes up again and gets a chance of handling the messages.
What you should do is schedule this logic every 10 seconds.
Drop a timer on your form and specify it to run each 10 seconds. Within the Tick event, call your custom action.
Thread.Sleep "stops" the current thread. if you only have one thread, everything is paused.
What do you want to achieve ?
Perhaps you need a second thread, or perhaps the better solution a timer which triggers a action every 10 minutes
s. Task.StartNew() or ThreadPool

c# console app using thread

I have a console app. I need to implement a do while that loop infinitely and a thread that at every 3 seconds returns a list of items from a page. How can I do that? I have a methold called getId( string URL) . how do I implement the thread in the do while?
Using System.Timers.Timer class:
string url = "www";
System.Timers.Timer timer = new System.Timers.Timer(3000);
timer.Elapsed += (o, e) => this.GetId(url);
timer.Start();
Timer is designed for use with worker threads in a
multithreaded environment. Server timers can move among threads to
handle the raised Elapsed event, resulting in more accuracy than
Windows timers in raising the event on time.
The Timer component raises the Elapsed event, based on the value of
the Interval property
I would not use a timer - what happens if the item retrieval takes longer than three seconds?
Can you live with a sleep(3000) loop?
Rgds,
Martin

Categories