WPF Dispatchertimer delayed reaction / freeze - c#

In my WPF application i use 3 different DispatcherTimers.
One is for displaying the current time
One is are for running a DB query every 5 sec
The third one refreshes a value for a custom button every 1 sec
When my program is running there are a lot of delays / freezes.
For example the time starts ticking correctly but on a sudden the value freezes up and after the freeze the time gets incremented by +3 seconds for example.
I am getting this behavior over my entire application.
What is the proper way to solve this problem with several timers?
EDIT:
I am having problems to replace a DispatcherTimer with a Timer from System.Timers namespace.
//new code with timer
timerW = new Timer();
timerW.Elapsed += new ElapsedEventHandler(timerWegingen_Tick);
timerW.Interval = 5000;
timerW.Start();
//OLD Working Code
timerW = new DispatcherTimer();
timerW.Tick += new EventHandler(timerWegingen_Tick);
timerW.Interval = new TimeSpan(0, 0,5);
timerW.Start();
Error : "The calling thread must be STA, because many UI components require this."
Best regards.

the DispatcherTimer is executed on the UI thread. So if the UI thread is busy for more than the interval, it will be executed when the UI thread is free to do so.
If you need more precise scheduling, you should go for a time than runs in the background (System.Threading.Timer, System.Timers.Timer). But don't forget about marshalling then.
hth,
Martin

I guess this is because they all are running on same thread.

Use System.Threading.Timer and when updating UI use the SyncronizationContext.Syncronize to run the updating code in.
Don't forget to get the context from SyncronizationContext.Current on the UI thread.

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.

From AS3 to C# a simple elapsed Timer

I need to set up a simple elapsed Timer in C# (MonoBehavior) that calls a method when complete, but can also be cancelled before finishing. If cancelled or stopped, it automatically resets its interval. I don't need anything fancy like threading.
Reading over the documentation on C# Timers https://msdn.microsoft.com/en-us/library/System.Timers.Timer%28v=vs.110%29.aspxstill a bit confused. For instance, when you set mytimer.Enabled=false does it also reset the timer back to 0? Perhaps I should be looking at Coroutines instead?(this is for Unity)
In AS3 I would do something like this
private var _delayTimer:Timer;
//create a Timer object that runs once for 1 second
_delayTimer = new Timer(1000,1);
//add handler
_delayTimer.addEventListener(TimerEvent.COMPLETE, onDelay);
//start timer
_delayTimer.start();
private function onDelay(e:TimerEvent):void{
trace('delay finished!);
}
//some other method to interrupt-stop and reset the delay timer
private function foo():void{
_delayTimer.reset();
}
By using System.Timers.Timer, you are using multi-threading - it's quite likely this is not what you want.
Instead, you probably want System.Windows.Forms.Timer - this will post the timer event back on the UI thread (if you're using Windows Forms, of course).
You can use Start and Stop the way you want, because there's actually no ticking clock - it just registers a callback from Windows in the future, basically.
Relevant piece of documentation from MSDN:
Calling Start after you have disabled a Timer by calling Stop will cause the Timer to restart the interrupted interval. If your Timer is set for a 5000-millisecond interval, and you call Stop at around 3000 milliseconds, calling Start will cause the Timer to wait 5000 milliseconds before raising the Tick event.

waiting for x hours before executing a function using timer does not work

I want to wait for x hours before executing some code in C#. i thought using a timer would be a good idea. (using thread.sleep does not seem right). But it just does not work. i am using the following code:
static void Main(string[] args)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = x * 3600000;
timer.Enabled = true;
timer.Elapsed += (o, e) => SomeFunction(username);
timer.AutoReset = true;
timer.Start();
}
this code supposed to wait for x hours and then execute SomeFunction but when i debug it, the main function ends after timer.start().
do you see any problem here? or can you suggest an alternative besides thread.sleep or await Task.Delay() ?
As soon as your Main function exits, your process ends, along with any background threads including timers.
You need to keep your main thread alive using Thread.Sleep(), Console.ReadKey() or whatever seems appropriate.
Alternatively, if you don't want to keep your process alive, you can register a scheduled task with Windows to be run in an hour's time, and then end.
There are two problems here. The first is that an executable will exit when all foreground threads are finished running. The only foreground thread is that going through Main() so it will then exit.
The second is that you aren't storing timer anywhere. Even if another thread was keeping the executable going, timer is eligible for garbage collection perhaps as soon as timer.Start() returns and certainly after Main() exits.
using thread.sleep does not seem right
It generally isn't a good idea, but considering that you only have one thread anyway, and considering that you have to have at least one foreground thread in an application, Thread.Sleep seems perfectly reasonable in this particular case. Task.Delay just as much.
More generally, I think I would prefer this to be either a scheduled task or a service. In particular, in cases where I want to wait hours before something is done, I very often want this to survive reboots.
Check out Quartz.Net and this for scheduled tasks.

Which thread will timer method run in?

I looking to run a method periodically but would like to optimise my code by having it run in a separate thread. So far my code looks something like below:
private System.Timers.Timer timerQuartSec = new System.Timers.Timer(250);
private Thread quarterSecThread;
timerQuartSec.Elapsed += new System.Timers.ElapsedEventHandler(someMethod);
quarterSecThread = new Thread(new ThreadStart(timerQuartSec.Start));
My question is, would this code simply start the timer or would the code (on TimerElapsed) run on the new Thread?
System.Timers.Timer will run on a ThreadPool thread as long as you don't set the timer's SynchronizingObject.
So there's no need to start a dedicated thread. You need to pay attention though if you want to access GUI elements.

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