Why does DispatcherTimer cease to fire after some random time? - c#

I have setup DispatchTimer correctly to fire every second-
OneSecondChecker = new DispatcherTimer();
OneSecondChecker.Tick += new EventHandler(OneSecondChecker_Tick);
OneSecondChecker.Interval = new TimeSpan(0, 0, 1);
OneSecondChecker.Start();
Problem: And it fires correctly for a certain period of time after which it just stops firing.
Additional Information:
Now you might ask what does it do? There is a class level (static) boolean variable that is set to true if the method OneSecondChecker_Tick() is running, and then is set to false if it is not, so that we don't have two instances of this method running at the same time even if it is set to fire every second. It is an application requirement to make sure OneSecondChecker_Tick() runs without any delay. I am also not trying to run in an infinite loop. There is a second check to see if a table value is updated to before OneSecondChecker_Tick() runs. It is that table value that "sort of" informs OneSecondChecker_Tick() to run. That table value is updated by another application.
Within the method itself I do have a call to run threads in parallel using TPL. I don't know if it has anything to do with it.
EDIT
I still haven't been able to figure this one out. It might be that the application is frozen. The task manager does not say that though. Is it possible to tell if the application is not responding from somewhere other than the task manager?

The problem is not with DispatchTimer. It wasn't even with TPL. The problem was elsewehre in the code running in an infinite loop and causing stack overflow - after which it stopped firing.

Related

Performance issues with background process WPF

In my app I need a process that will work in the background and check for changes for various things. Then do some logic. Most of the time this process will be idle and just be waiting for the trigger point. So this is what I did:
private void MyBackgoroundThread()
{
while (isRunning)
{
if (MyStatus == 1)
{
//Log removed
}
}
}
Then at run time it would be called by the constructor with the follow;
await Task.Run(() => MyBackgoroundThread());
Now this works perfectly. The problem now is that my app when idle uses about 35% CPU usage. Disabling the MyBackgoroundThread the app uses 0% CPU usage at idle. So I know it's this thread.
I understand why this is happening but my question is what is best practice for handling this situation so I don't burn 35% CPU for doing nothing.
Edit: based on comments;
#Dour High Arch Explain what “the trigger point” is
Basically the variable MyStatus is a global variable that when the process has to be "triggered" the status gets change to 1 for example. Sorry thought was clear in the code.
#Ron Beyer This seems dangerous given that the "background" task is an
infinite loop, how is the await supposed to return?
Well you are at the meat of the issues. The global variable isRunning gets changed to false on the app closing. I am looking for a better solution
You are using 1 CPU, more or less, to constantly iterate your while statement.
The best solution depends on what you are doing in that code. If at all possible, use an event or similar notification to trigger background work rather than a polling thread. For example if you're looking for changes to files, use a FileSystemWatcher.
If your code, rather than an external agent, is causing the need to do work, you can also consider a Producer/Consumer pattern. In that case, have a look at BlockingCollection, which makes implementing that pattern a snap.
If there is no way to use an event-based notification mechanism to trigger the background work, you can use Thread.Sleep() to at least have your polling thread sleep for a time, until it has to wake up and check for work again.
UPDATE based on your edits
basically the variable MyStatus is a global variable that when the process has to be "triggered" the status gets change to 1 for example. Sorry thought was clear in the code.
Change it from a global variable to a static property, and have it fire off an event when the value is changed. Instead of using your polling thread, have some code that subscribes to your new event.
The global variable isRunning gets changed to false on the app closing.
A background thread will automatically close when the application closes.

Strange if-statement behavior with zero value double

Would anyone care to explain to me how the value of this.oBalance.QouteBalance is evaluated to be true for being less than zero when it clearly isn't? Please see image below.
Am I missing something fundamental when it comes to comparing doubles in C#??
public double QouteBalance { get; set; }
UpdateBalance_PositionOpenned() is not being called in a loop, but is being called as part of a more complex event driven procedure that runs on the ticks of a timer (order of milliseconds)
EDIT: Pardon the code if it's messy but I couldn't edit it as this was a run-time error after quite a long run-time so was afraid wouldn't be able to recreate it. The Exception message is not correct and just a reminder for myself. The code after the exception is code I forgot to comment out before starting this particular run.
EDIT 2: I am building and running in Release Mode.
EDIT 3: Pardon my ignorance, but it would seem that I am in fact running in a multi-threaded environment since this code is being called as part of a more complex object method that gets executed on the ticks (Events) of a timer. Would it possible to ask the timer to wait until all code inside its event handler has finished before it can tick again?
EDIT 4: Since this has been established to be a multi-threading issue; I will try to give wider context to arrive at an optimized solution.
I have a Timer object, which executes the following on every tick:
Run a background worker to read data from file
When background worker finishes reading data from file, raise an
Event
In the event handler, run object code that calls the method below
(in the image) and other multiple routines, including GUI updates.
I suppose this problem can be avoided by using the timer Tick events to read the from file but changing this will break other parts of my code.
You're accessing shared variables from multiple threads. It's probably a race condition where one thread has thrown the error but by the time the debugger has caught and attached, the variable's value has changed.
You would need to look at implementing synchronizing logic like locking around the shared variables, etc.
Edit: To answer your edit:
You can't really tell the timer to not tick (well you can, but then you're starting and stopping and even after calling Stop you might still receive a few more events depending on how fast they are being dispatched). That said, you could look at Interlocked namespace and use it to set and clear and IsBusy flag. If your tick method fires and sees you're already working, it just sits out that round and waits for a future tick to handle work. I wouldn't say it's a great paradigm but it's an option.
The reason I specify using the Interlocked class versus just using a shared variable against comes down to the fact you're access from multiple threads at once. If you're not using Interlocked, you could get two ticks both checking the value and getting an answer they can proceed before they've flipped the flag to keep others out. You'd hit the same problem.
The more traditional way of synchronizing access to shared data member is with locking but you'll quickly run into problems with the tick events firing too quickly and they'll start to back up on you.
Edit 2: To answer your question about an approach to synchronizing the data with shared variables on multiple threads, it really depends on what you're doing specifically. We have a very small window into what your application is doing so I'm going to piece this together from all the comments and answers in hopes it will inform your design choice.
What follows is pseudo-code. This is based on a question you asked which suggests you don't need to do work on every tick. The tick itself isn't important, it just needs to keep coming in. Based on that premise, we can use a flagging system to check if you're busy.
...
Timer.Start(Handle_Tick)
...
public void Handle_Tick(...)
{
//Check to see if we're already busy. We don't need to "pump" the work if
//we're already processing.
if (IsBusy)
return;
try
{
IsBusy = true;
//Perform your work
}
finally
{
IsBusy = false;
}
}
In this case, IsBusy could be a volatile bool, it could be accessed with Interlocked namespace methods, it could be a locking, etc. What you choose is up to you.
If this premise is incorrect and you do in fact have to do work with every tick of the timer, this won't work for you. You're throwing away ticks that come in when you're busy. You'd need to implement a synchronized queue if you wanted to keep hold of every tick that came in. If your frequency is high, you'll have to be careful as you'll eventually overflow.
This isn't really an answer but:
UpdateBalance_PositionOpenned() is not being called in a loop, but is
being called as part of a more complex event driven procedure that
runs on the ticks of a timer (order of milliseconds)
see:
Multi-threading? – abatishchev 30 mins ago
Tight timer driven event-loop on the order of milliseconds probably has all the problems of threads, and will be almost entirely impossible to trouble-shoot with a step-through debugger. Stuff is happening way faster than you can hit 'F10'. Not to mention, you're accessing a variable from a different thread each event cycle, but there's no synchronization in sight.
Not really a full answer but too much for a comment
This is how I could code defensively
Local scope leads to less unexpected stuff
And it make code easier to debug and test
public void updateBalance(double amount, double fee, out double balance)
{
try
{
balance = amount * (1.0 + fee);
if (balance < 0.0) balance = 0.0;
}
catch (Exception Ex)
{
System.Diagnostics.Debug.WriteLine(Ex.Message);
throw Ex;
}
}
Value type is copied so even if then input variable for amount changed while the method was executing the value for amount in the method would not.
Now the out balance without locks is a different story.

correct way to handle exit from infinite loop in c#

In my apps i find the need to have infinite while loops mostly to do some repeated action continuosly unless another event takes place so what i am doing is
while(chkFlag)
{
//do something here which takes around 30 seconds
}
Then in some other event say a button press to stop the loop i do
chkFlag = false;
Now this does the work but the problem is this does not stop the loop instantaneously as the chkFlag is checked only after the complete execution of the loop takes place. So can anybody please tell me how i can exit a loop instantaneouly based on an event.
The "blocking" code should likely be moved into some kind of worker thread (which can be terminated and/or have the results discarded). If using a BackgroundWorker (recommended, as it makes this simple), there is built-in support to handle a cancel operation.
Then the loop can either be moved inside the BackgroundWorker or the completion (RunWorkerCompleted) event of the worker can trigger the next worker to start (which causes an implicit loop).
Happy coding.
There are more "aggressive" ways of terminating/signaling a thread; but suggesting these would require more information than present.
you can't make it exit instantly (well, you could run the loop in a new thread and Abort it, if it's really safe to have an exception thrown from it at any time), but you could scatter if(!chkFlag) break; at various points within the loop that it's safe to exit. The usual method of doing this is to use a BackgroundWorker or a CancellationToken rather than a simple boolean flag.
Of course, it will still need to be run in another thread so that the button event can run at all. BackgroundWorker will take care of this automatically.
You are looking for break;.
I suppose, based on the anonymous downvoter, I should elaborate. The syntax above will immediately exit the loop that you are in (it works in the other loops as well; it's probably worth noting that continue exists to restart the loop at the beginning, which will perform increment logic in for-style loops).
How you decide to execute break is up to you, but it must be within the loop itself.
There are multiple approaches to this, such as placing checks for the event within the loop and calling break; if it occurs. Others have noted the other approaches with BackgroundWorkers and Cancel Tokens (this is preferred given it's not within the loop).
Is it possible you want to use a new thread? What are you doing for 30 seconds in the loop. Sounds like maybe there's a better design to use.
Have you considered using a timer, or setting up an event handler?

Triggering actions using Timer in C#

I am developing an application in C# 4.0. I need to call a method depending on the current system time. Can I do it using Timer control? It would be great if someone could tell me how to do this.
Thanks,
Rakesh.
You may (and without knowing more about your app I cant say for sure) want to look at it a bit differently. You can easily write an app that sits around, doing nothing except polling what time it is, and then running whatever it is you need to do, but that will leave your application hanging around and doing nothing but taking up resources most of the time.
Instead, maybe you could consider creating a scheduled task, which will let you run your app at any given time. The Task Scheduler is documented at http://msdn.microsoft.com/en-us/library/aa383614(VS.85).aspx, and there is a managed wrapper for it at http://taskscheduler.codeplex.com/. (it says it works on XP or better, so hopefully it will cover your needs).
Good luck,
You can use the below code
System.Timers.Timer _timer1 = new System.Timers.Timer();
_timer1.Elapsed += new ElapsedEventHandler(_timer1_Elapsed);
//1 second
_timer1.Interval = 1000;
_timer1.Start();
//this event will be fired each 1 second
private void _timer1_Elapsed(object sender, ElapsedEventArgs e)
{
}
You should be able to, yes. Ghyath Serhal has told you how to use the timer class in general. The only bit missing is how to do it at a specific time. This should be pretty easy - when you set up the timer just take the time you want the action to happen and the current time, find the difference in seconds and use this to populare the interval. You'll also want to set the AutoReset property to false so that it doesn't start counting down immediately again.
If you ever change the time that the events happen you just need to hook into this with a trigger and update the timer to the new time.
Edit to add: If somebody were to change the system time that may cause problems with this plan. I'm not sure if you can easily tap into that to reset your timers. I'm guessing probably not relevant though. :)
The problem with timer is that it does not guarantee that the elapsed event would be called exactly at the right moment - all you know is that it would be called after time that is bigger than the Interval.
The solution is dependant on the resolution of the time you're interested in - for example if you need to check each minuet if a specific event occurs you can set a timer to raise the event every minuet and then use DateTime.Now to check if the system time is the time the event should occur.
A good policy is to always expect the timer elapsed event to happen several seconds after the Interval set depending on how busy the system is.

How can I have a WinForms program do some **specific thing** whenever a certain time-based condition is met?

How can I have a WinForms program do some specific thing whenever a certain time-based condition is met?
I was thinking I could do something with two threads, where one thread runs the normal program, and the other thread merely loops through checking if the time-based condition is true yet or not, and when the condition is true it signals an event.
However I am unsure of the best way to do it. Where in the program would I call the two threads? Maybe I am thinking about it all wrong?
How would you do this?
MORE INFO:
What it has to do is check the data.dat file and see when the last time it was updated was. If it was a month or more then do the specific thing. Could this still be done with a Timer?
NOTE:
I think it might be useful to note the difference between the System.Timers and the System.Windows.Forms.Timer...
I think you should use a Timer set to an inteligent interval to check if your time-based condition is met.
It depends what your time-based condition is. Is it a special time or an interval after which you want to do something special? If it's the second, you can just use the Timer and do what you have to do when the Timer.Elapsed event is fired.
Edit after your edit:
If you want an event to be fired every time the file changes, use a FileSystemWatcher
Edit2:
Here's the difference between System.Windows.Forms.Timer and System.Timers:
The Windows Forms Timer component is
single-threaded, and is limited to an
accuracy of 55 milliseconds. If you
require a multithreaded timer with
greater accuracy, use the Timer class
in the System.Timers namespace.
You could add a System.Windows.Forms.Timer control to your Form (see the Components category in the toolbox).
Then set the timer's interval to some value (e.g. 1000) and add a handler for its Tick event. This handler will then be called once every 1000 milliseconds.
In the handler you can then check if the conditions are met and if yes, start your specific operation.
Update (after you updated the question):
To check if the last modification of a file was more than one month ago, you can use this code:
if (File.GetLastWriteTime("data.dat").AddMonths(1) < DateTime.Now)
{
// do whatever has to be done
// if it is a time-consuming task, start a new thread!
}
You can still put this into the Tick event handler of the timer component. But in that case it does probably not make sense to fire the timer every second.
Depending on your application (e.g. if it will be started quite often), another possibility would be to execute the above check during the startup of your application.
Regarding your 'more info':
How many times must it check the modification-date of that specific file ?
Only once (during startup for instance), or should it check the modification-date of that file multiple times during application execution ?
If it has to be done only once, then it is useless to use a timer.
If it has to be done multiple times, then yes, you could use a timer.
The eventhandler of the Elapsed event could then check the ModificationDate of the file, and see if action needs to be taken.
Another solution, which is probably more elegant, is using a FileSystemWatcher.
This FileSystemWatcher could 'watch' that particalur file.
Specify a Filter on the FileSystemWatcher so that, every time the particular File is changed, an event is raised.
In the eventhandler of the FileSystemWatcher, you can then take the necessary action:
FileSystemWatcher dataFileWatcher = new FileSystemWatcher();
dataFileWatcher.Path = "path to your file";
dataFileWatcher.Filter = "yourfilename";
dataFileWatcher.Changed += new FileSystemEventHandler(OnFileChanged);
dataFileWatcher.NotifyFilter = NotifyFilters.LastWrite;
dataFileWatcher.EnableRaisingEvents = true;
private void OnFileChanged( object sender, FileSystemEventArgs e )
{
// take action.
}
Note however, that there's a sublte bug / feature in the FileSystemWatcher which causes that the Changed event gets raised multiple times for one change to the File you're watching.
You can resolve this like this
Another alternative, if you know the time between file updates (a month) is to check once at startup time. If the file is out of date you can process it immediately. If not, you can then work out how long you need to wait before checking it again. You can then schedule a task using a wait timer or other methods as described in the answers.
Basically, at startup time you can find out the limit/worst case on how long you have to wait and then you don't need to do any additional checks in the meantime. This assumes of course that the file can't be changed to an OLDER version during the running of the program which seems unlikely, but not impossible!

Categories

Resources