Wpf Dispatcher timer going erratic - c#

I have a dispatcher timer which has to act like a heartbeat every 500ms and write on a register on an anybus. I have set it with maximal priority:
m_HeartBeatTimer = new DispatcherTimer(DispatcherPriority.Render);
the problem is that when program is running sometimes the interval can enormously get longer up to 19 seconds:
[20/06/2017 17:00:01.182] HeartBeat 1 79
[20/06/2017 17:00:20.669] HeartBeat 0 80
of course there are other timers and other operations but shouldn't the timer be insensitive of those ones?
Is there any way to make it respect the correct timing?
thank you

.net has several types of timers. The Windows.Forms.Timer and DispatcherTimer both run on the UI thread. They only tick when the UI thread is not busy.. if the UI thread is locked into some task then the tick waits until the task is done.
If you want a true heartbeat then I recommend using System.Threading.Timer instead. This one will tick on a worker thread, so keep that in mind.
private System.Threading.Timer _timer;
private void go()
{
_timer = new Timer(_ => Timer_Tick(), null, 0, 1000 * 10); //every 10 seconds
}
private void Timer_Tick()
{
//this is not the main UI thread. Must invoke if you want to interact with the UI
}

Related

Stop creating new thread while system.timers.timer elapsed called

I am facing a issue when used to system.timers.time, i have a running process in my application.
with timer called my process start, but i want to use that process within the thread only.
because every time timer elapsed event called the new thread has been generated, but i want to prevent this and only using single thread in a process.
Here is my code.
Public void Watcher()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 3000;
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
}
Public void OnTimedEvent
{
// process code here
}
Here, after every 3 seconds OnTimedEvent called and new thread created, but i don't want to create new thread every time.
So, how to prevent this, any idea?
If you have a UI you should simply use forms timer or dispatch timer. If you do not have a UI you can set the SynchronizationObject of the timer. This will be responsible for marshaling the execution to the right thread.
I would probably skip the synchronization object, and just do the marshaling in the event handler of the event.
In either case you will need some kind of message loop if you do not have a UI. This would have a threadsafe queue where the thread takes a message and process it, one at a time. For example, using a blocking collection of Action.
As mentioned by #MindSwipe in the comments. A new thread will not be generated per event. It will simply take threads from the threadpool. So the number of threads used should be fairly constant. The main reason for moving all execution to one thread is because it can make threadsafety easier to manage.

Pausable Timer on separate thread

I need timer running on separate thread that can be paused and resumed.
The System.Threading.Timer would be ok. but I notice that it spawns new threads even while I'm debugging the callback. I don't want next callback to started before first one is finished, I would like to pause the timer during execution of the callback.
The System.Threading.Timer cannot be paused.
I'm not going to measure any time so no System.Diagnostics.Stopwatch.
In this qestion someone implemented his own class deriving from Timer but I have no idea what timer is this - the System.Threading.Timer is sealed.
System.Windows.Threading.DispatcherTimer can be stopped but the callback is dispatched on UI thread and I'm not sure about portability of this class.
What should I do?
You could instead of using a timer just make it a loop with a delay:
public static async Task RepeatingTask()
{
while(true)
{
Console.WriteLine( "Doing cool stuff" );
await Task.Delay( 2000 );
}
}
And you can start it like this:
Task.Run( RepeatingTask );
NOTE: this will not do the trick if you need to fire every say 2 seconds exactly.

How to create an application loop in C#

I have a console server in C# that keeps running in a while(true) loop. But that takes > 50% CPU even if it is doing nothing. I tried Thread.Sleep it worked! Not eating my CPU anymore but, it do not resumes in the exact time specified and is not considered good practice. Am I doing the right thing? Or is there any other way than using while(true) and Thread.Sleep?
When you want to suspend thread for a while without consuming CPU resources, you usually use some WaitHandle (such as AutoResetEvent or ManualResetEvent) and call it's WaitOne() method to suspend thread until event that is supposed to wake it up occurs (e.g. key is pressed, new network connection arrives, asynchronous operation finishes, etc.).
To wake up thread periodically, you can use timer. I'm not aware of any timer in .NET Framework, that provides WaitHandle (of course you can easily create such class yourself), so have to use Timer and call AutoResetEvent.Set() manually on each tick in it's callback.
private static AutoResetEvent TimerWaitHandle = new AutoResetEvent(false);
static void Main()
{
// Initialize timer
var timerPeriod = TimeSpan.FromMilliseconds(500);
Timer timer = new Timer(TimerCallback, null, timerPeriod, timerPeriod);
while(true)
{
// Here perform your game logic
// Suspend main thread until next timer's tick
TimerWaitHandle.WaitOne();
// It is sometimes useful to wake up thread by more than event,
// for example when new user connects etc. WaitHandle.WaitAny()
// allows you to wake up thread by any event, whichever occurs first.
//WaitHandle.WaitAny(new[] { TimerWaitHandle, tcpListener.BeginAcceptSocket(...).AsyncWaitHandle });
}
}
static void TimerCallback(Object state)
{
// If possible, you can perform desired game logic here, but if you
// need to handle it on main thread, wake it using TimerWaitHandle.Set()
TimerWaitHandle.Set();
}
I can't comment, so i'll put it here.
Theorically with Thread.sleep(1) it won't use that much CPU.
You can get more info from this question/answer: What is the impact of Thread.Sleep(1) in C#?
You can use System.Threading.Timer class. It Provides a mechanism for executing a method on a thread pool thread at specified intervals.
Example
public void Start()
{
}
int dueTime = 1000;
int periodTS = 5000;
System.Threading.Timer myTimer = new System.Threading.Timer(new TimerCallback(Start), null, dueTime, periodTS);
This will call start method after 1 second from calling it and after that start will be called after every 5 second.
You can read more about Timer class here.

how to set timer for each different thread in window service

trying to set timer for each different threads with different timings , as far as i know if we set a timer in main method the same will works for all the threads, so i want to know how to set timer for each different thread with out killing the threads, kindly advice on this please
static Timer _timer;
static void Main(string[] args)
{
_timer = new Timer(10000);
_timer.Enabled = true;
_timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
}
the above pasted code will do job for all of the threads will run for every ten sec, how ever all threads will run for every ten sec by the timer in main method, my concern is have to set timer for each thread with different timing
Summary:
why i asked like this question, here i have requirement of window service,what is to do means,For example in a window service having a three different threads(XYZ,ABC,PQR), if i start a service,all the three threads to be intialized and those threads should to be acts as For which based on timer settings which we are passing from the app config,these thread has to be fire based on the timings has setted,kindly advice
If you want to start some threads after a given time, you can use System.Threading.Timer.
int[] times = new int[] { 10000, 14000, 17000 };
foreach (int time in times)
{
System.Threading.Timer t = new System.Threading.Timer(MyTimerCallback, null, time, 0);
...
}
private void MyTimerCallback(object state)
{
//Do some awesome stuff
}
Have you tried to use the [ThreadStatic] attribute?
This attribute defines that the veriable it coupled with will not be shared between threads, and a copy of him will be created for each thread.
[ThreadStatic]
static Timer _timer;
void MyThreadStartMethod()
{
_timer=new Timer(value);
...
}
And also, i don't see any threads in your code. The Main method is called by the CLR to start the application, and runs each time in a different process.

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

Categories