I have an asp.net web application that uses a timer to update all clients with new data. The data isn't in a database but is in a public static object shared by all clients. The timer has an OnTick method that updates each client's controls with this global data so all clients can view the most recent data. I'd like to update data fairly quickly, so I have the timer's interval set to 1 second.
The issue I've been seeing since implementing this timer is that sometimes button presses don't do anything. Sometimes (at random) the user has to click the button twice or more for anything to happen while other times a click works the first time. My guess is the button presses that have no effect happen because they were pressed at the same time the timer was executing the OnTick method (please correct me if I'm wrong). I set the timer interval to a much longer period and I didn't see these ineffectual button presses, so I know it has something to do with interference from the timer.
Is there an alternative to using timers and OnTick to update all client controls (without requiring each client to initiate or request the update)? Is there an event-driven way to update all clients rather than relying on a timer (i.e. all clients update on change in global data/on calling a certain method in the server code rather than at a set interval)?
Related
So I have a Timer object that I'm going to call time, and time has a tick event that is called after 60 seconds are passed. I'm trying to use the time.Stop() method, but the time_Tick() is still called. How do I prevent the Tick method from occuring? Once the Timer has started is there no way of backing out? Thanks! I'm new to Tick events.
Timer ticks can arrive concurrently and after the timer has been stopped (for fundamental reasons). Ticks could be queued right before you stop the timer.
If you want to reliably stop a timer set a boolean flag and inspect that flag in the tick event handler. If it's set ignore the tick.
You need to synchronize access to that flag.
If you have other timer objects you may be seeing this:
Calling Stop on any Timer within a Windows Forms application can cause messages from other Timer components in the application to be processed immediately, because all Timer components operate on the main application thread. If you have two Timer components, one set to 700 milliseconds and one set to 500 milliseconds, and you call Stop on the first Timer, your application may receive an event callback for the second component first. If this proves problematic, consider using the Timer class in the System.Threading namespace instead.
How can I detect if the Application has been idle for let's say 30 seconds?
I know this is possible by using a DispatcherTimer and then restarting it at PhoneApplicationPage.ManipulationCompleted event? But, I am concerned as this will affect the performance of the application.
Are there any better solutions?
You're on the right track. There isn't an explicit "idle" notification (especially not one that fast).
ManipulationCompleted may not always fire for you since other input can prevent the manipulation from starting and a user could do a very long manipulation. I'd reset the timer on any mouse input rather than just on ManipulationCompleted.
Depending on how exact you need your 30 second timer to be I would consider leaving the timer running and setting a flag for the last input. When the timer expires then check if the flag has been set. This way you won't need to continuously reset the timer for every user input.
I have written the basis for a reminder application using c#/wpf.
I am wanting to notify the user by a popup of some sort when a reminder is active.
I am not to sure how to go about when the application is doing nothing while it waits for the next reminder to be active.
Any ideas or help is appreciated
Edit*
What class's i would use
I think you're looking for a timer.
At your application startup and every time you add, change or delete a reminder, you look up the first existing reminder (in chronological order) and sets the timer to the time between now and the set reminder time.
When the timer callback is called you locate the correct reminder and act on it.
I have been reading loads about timers, and options for achieving my goal, and I believe I need to use system.timers.timer and set the interval correctly.
I think I know how to do this but what I am unsure of is where to do it, do I do so in my view, my controller, global.asax?
Maybe I shouldn't use a timer at all?
What I'm looking for is the best way to run an if statement on the hour, every hour, and update the view depending on the results of that if
Usually a web app (MVC or WebForms) isn't the best place to run scheduled tasks. It can be done, but you will get things like IIS recycling application pools and other anomalies, which although useful to a web app, could get in the way of reliably scheduling tasks.
A lot of developers (and my favourite too) schedule their tasks in a Windows Service. This can be installed and can be set to gracefully start and stop when the server starts and shuts down. You can then set up logging and other health monitoring to monitor the state of your scheduler service.
However if your tasks is purely SQL based you may wish to use SQL Server's inbuilt scheduling (or similar for any other database). Another alternative is to use the operating system's scheduler.
Edit
In regard to updating your view with the results, you can store and update the status of your scheduled tasks in the database with columns like 'TaskStatus' (New, Waiting, Running, Aborted, Failed, Cancelled, Completed) and 'TaskResult' (probably empty for success or the error message from a failure). You can then show and filter this information on your results view by retrieving it from the database.
JavaScript - On Your Page:
You can redirect to the controller > action that is your required function through JavaScript:
<script type="text/JavaScript">
setTimeout("location.href = '/YourDefineUrlPathHere';",1500);
</script>
HTML Meta tag - On Your Page:
Other is you can do it through meta tag if you want to call your view action again (in other words refresh it)
<head>
<meta http-equiv="Refresh" content="15;url='/YourDefineUrlPathHere'">
<!—‘15’ is number of seconds you want to wait-- >
</head>
Timers – in your controller
aTimer = new System.Timers.Timer(10000);
aTimer.Elapsed += new ElapsedEventHandler(YourMethodHere);
aTimer.Interval = 2000;
aTimer.Enabled = true;
See MSDN: Timer
Timers are not very efficient solution if you want to keep caaling for a long amount of time
However another way and I guess more ‘standard’ way to achieve your result could be through Window Services if you want to pursue it in this direction this link might help you a lot.
Introduction to Windows Service Applications
What do you mean by "update the view"?
An MVC View is a class - you can only "update" objects as they have values. Views are instantiated when a user requests the page.
If you mean you want the user to have a page open in their browser all the time and it gets refreshed every hour, then you could use a timer in javascript on the client to reload the page every hour.
If you mean you want to update the results of any user opening your page depending on data that changes every hour, you can store the last update time in your database and then when the view runs check if the data is more than an hour old. If it is, run your if statement in your controller.
Use Azure Functions. You can run scheduled tasks using a timer trigger. It's pretty good.
https://learn.microsoft.com/en-us/azure/azure-functions/functions-overview
Hopefully someone can help me to look in the right direction for a solution to this issue I've come across during the design of a system.
I am creating an auction site in which the auction has a particular end date/time.
I have a .NET Timer displaying the remaining time to the user and when this countsdown it fires and event to update the back end SQL database to say the auction has completed and it informs the winning user and fires a CLOSE function.
How would you recommend doing this for auctions that aren't physically open in a browser at the time so the Timer event never creates this CLOSE event.
Ideally I need to run something at the point in time when an auction closing time has passed?
Thanks
One option is to store in the database the date/time that the auction item ends/closes. Then, don't worry about something reacting to it closing (timer in your case on the client) and updating it closed. What determines it's closed is simply the fact that now > closed date/time.
EDIT:
In the comment below you stated you also need to send mail when an auction closes. If that's the case, you need some sort of background processing to select all events that are closed and send mails. You can still define closed by storing a date time. That bg processing can select all events where now is greater than closed date and processed bit is false. Once you select those, put them in a durable queue (table in sql, azure queue etc...). Then have the background processing drain the queue. As it processes each item and sends mail, it updates the event as processed.
You have multiple options for background processing:
Windows Service
In proc timer with a threadpool to process (only do this if you have one AT)
Worker role in Azure
Sql Agent Job
Write a Windows service that polls the database at a set amount of time (I'd say a little less than the minimum length of an auction. For an example, say a day). That service would store in memory actions that will end within that amount of time, and check every second whether there are actions that ended. For auctions that have ended, fire your CLOSE event.