Conducting timed tasks in a web-site - best practice? - c#

What might be the best way to implement timed-task in a web-site (asp.net) environment ?
Say clicking a button locks it for 4 hours, or a day. How would I go about implementing the process of counting those 4 hours, (or 1 day) and then unlocking the button) ?
Keep in mind this is a web-site: Do I
save the current datetime stamp to the DB (I'm logged in as a registered user to the web-site)
every time I visit the page with the button I retrieve the stamp and the duration
and calculate how much longer I have to wait, until the button is unlocked.
(And possibly implement a JS (for example) count-down counter that would show near the button)
I'd assume using session variables or cookies is a bad idea, as I may close my web-site or delete my user data and thus loose the above.

Since your requirement is to support this across sessions, then it definitely needs to be in the DB.
DB
Add a LockedUntilUtc column that indicates the date/time that the button should unlock. Better yet, name the column to represent the business model. Maybe you are writing an HR app the has a raise approval process, and there is a mandatory 7 day waiting period before the manager can release the raise to allow HR to review, and the button is laballed "Publish Raise" in which case I'd name it something like PublishRaiseAvailableUtc.
I've dealt with lots of scenarios like this, and it's often simpler to use the date/time that an event needs to occur. As opposed to saving the beginning of the timer and always having to add 7 days everytime you need to make a calculation.
UI
Send this value down with the page as a hidden value. Write javascript using the framework of your choice, or just something as simple as setTimeout which will fire to unlock the button at that point in time.
Do not worry about trying to come up with a convoluted way to prevent the user from unlocking the button by manipulating the HTML. You should assume they can unlock the button if they put effort into it. Given that assumption, we need server side logic to validate the request.
Server Post Validation
When the user clicks the button, and the POST is sent to the server, then server-side code should retrieve the value of PublishRaiseAvailableUtc from the database(do not trust the value posted from the hidden field), and compare that to the server time. I.e. server time should be greater than the PublishRaiseAvailableUtc, assuming you ensure you are comparing UTC times.

I think the best way is saving the day when the button becomes unlocked again. And every time the page is loaded, retrieve that info from the db to check if it should be locked or not.
Another possible way is to use an application variable. But i dont recommend this, because data is stored in memory and because if you reset the app or server, data will be lost.

You first problem is in your approach. You don't necessarily care how long it will be until the time you've saved, but you definitely do want your button to change when that time comes.
What I might suggest is to load the DateTime value from the database, place it somewhere in the page where JavaScript can read it. Now, one only problem is that some users may be able to locate and modify this value to skip the timer. I'm not personally familiar with a way to circumvent this easily, but you should be able to research a solution.
Once you have the value readable by JavaScript, a loop is probably going to be your best bet for checking the current time against your saved time, then performing whatever action you want.
A do..while loop will probably suit your needs
To avoid performance issues, use setTimeout to delay each loop iteration. The delay doesn't have to be very significant.
In the loop, retrieve the current date and time, then compare it to the date and time you saved in the database. If the current date and time is greater, perform your action.
Now, my idea may not be optimal, but I feel it is at least a step in the right direction. I also suggest a loop so that the user is not required to refresh the page to see what changes resulted from the performed action.

Do not rely on client side validation that the button is locked/unlocked. Always check server side that the click happened during the allowable time. This would prevent someone from "hacking" the page to allow a click outside of the allowable window.

Related

how to handle system wide key events in asp.net application

i am working on an asp.net web application, where tasks are assigned to users, we set standard time to every task, in that standard time period the user has to finish the task, there are two buttons on the page, proceed and save, when a user clicks on proceed button, the time is saved in database as starttime, and when the user clicks on save button, the time is saved in database as endtime. this way we are capturing the time period within which the user is completing the task.
the standard time is set on an average time study basis, not every time the task takes the same amount of time.
often users can complete the task in very less time than the standard time, in this case the users are proceeding the task and even after completing the task, instead of saving it, they lock the system and go for tea breaks and after coming from break, they save the task.
i want to save some information on the web page when they lock the pc even when the browser is minimized.
i tried implementing applet using jintellitype library but its not capturing the key combinations that are used by windows os.
i also tried using Silverlight but there is no such support as in winforms application in Silverlight, i have to create a com component or something that interacts with system32 or some native api. it doesn't seem easy for me, i would like to know if there is such library for Silverlight.
it should be browser independent, i haven't tried ActiveX, but i think it can be done using ActiveX, but i don't want to use ActiveX as it runs only on IE.
i want to know all the possible solutions to achieve this.
thanks in advance.
Why don´t you set a kind of timer-check to know if the last time is too far from the correspondent (and previewed) time to perform the job? If a task may expend, for instance, from 1 to 5 minutes, have 21 minutes is too far.
Why din´t you create a timer to TIMEOUT user? If users know they will be timed-out after some time, probably, they won´t leave to coffre-break during the test (a kind of penalty must be aggregated on this, like start from the initial point if timeout).
Why don´t you automatically save the record after the job finish, instead obly the user to press a button?
Until I know, you can perform SUSPEND mode, but not detect them if started from other apps.

Firing events on regular time intervals (coming from database) using ASP.Net C#

Please check the image below.
Below I have a simple lottery system where I have these columns,
Vistors : Total no visitors till date
Next DrawTime : Will come from database (no problem with this)
TodayDate : Current IST Date(noproblem with this)
CurrentTime: Current IST time with seconds ticking like clock.
Result
TimeToDraw : Here we have main problem. Here we need is again ticker with minutes and seconds. For example if its get 15mins from db then the field will display 15:00 and on each second it will get decremented like 14:59,14:58... and so on. when the timer reach zero 00:00, i need to execute some server side code that will draw the result based on data saved in db, without reloading the entire page.
I am feeling lost. Please help me.
I have tried few links , but did'nt get any satisfactory result. Here are the links
Call js-function using JQuery timer
http://r4r.co.in/asp.net/01/tutorial/asp.net/How%20to%20make%20CountDown%20Timer%20in%20ASP.NET%20Using%20c-sharp.shtml
Javascript event triggers based on local clock
How to periodically update server-side value on webpage?
Requirements (Update):
Implementation of Minutes:Second(MM:SS) ticker using server side or client side scripts.
How to fire event when the ticker reaches zero(00:00)?
Again after drawing result, ticker will get reset to 15 min/30 min or whatever coming from database.
Please I need purely ASP.Net and C# (if possible) code. Any reference or link will be higly appreciated.
Thanks in Advance
Do NOT poll the server every second, that will create too much unneeded trafic.
Put a timer in the page (javascript) and when the timer reaches 0 poll the server.
The server should keep track of the time by itself; not relying on the client to provide the (potentially spoofed) time and pass back the appropriate response either winning tickets or nothing if it's not time yet to draw.
If you really need/want to push information from a server to the clients I recommend having a look at the suggestions here: https://stackoverflow.com/questions/6883540/http-server-to-client-push-technologies-standards-libraries
For SignalR have a look at this sample it is very close to what you need.
Do NOT use server side code to update the time on webpage unless it is critical.
For the countdown script look at the answer to this question: Javascript Countdown
When the timer reaches zero, refresh the page or execute an Ajax call using jQuery. When the call returns update the page depending on the server's response.
If you need more explicit answers you need to show what you have tried and point out problems you are having.

Handling unexpected events in winform application

I have a win-form application developed in .net 4.0 and using SQL 2008 as DBMS.
User can open an item from a list of item and every time they open, I am updating the database with the userId to state the particular item is opened by particular user so other users can’t open the same item at same time. Also when user closes the item I am resetting it back to normal where others can open.
But I am wondering how to update the database if some ones system got crashed/stuck or something similar. Is there any good solution to handle these kinds of situations?
One solution would be to add a time stamp column into the data table. Every time a user accesses an item (in addition to other work) you set this time stamp value.
You can then have a separate task/service that iterates thought the records and releases any expired locks once in a while.
So you're trying to implement your own locking mechanism. See how to mitigate the problems of Deadlocking that should give you an idea. Basically either you use notifications or stamps to track lock's owner status (if it's dead or still using the resource), preventing resource starvation.
Requested example
There are 2 users. User A and User B.
User A open a view within your app, then two things happen:
You update the DB and set the stamp to the current time.
You start a new background thread who will be responsible to mantain the lock. This background thread must wait N-Delta where N is the maximum minutes the resource can be locked without renew and delta is the delta for update time. So, for example, suppose a view can be locked for maximum 15 minutes without user activity, then your thread must wait 15-1 (taking that will probably take 1 minute to notify DB "better be caution with this time").
Then User B try to access to that view, you check on the db for the resource and for the lock table and if there's a lock on that view whose time isn't superior from 15 minutes then you deny access. BUT if time is most that 15 minutes you grant the access to the User B and remove the access from the User A.
If either User A or User B successfully close the view, then you just remove the entrance from the DB.
This is a very simple example but should give you an idea of what I mean.
I have faced similar situation before. In such cases you will have to assume how much maximum time would a user take to action on that item (say 15 mins). Create a table called item_lock with 2 columns: item_id, lock_aquired_time. Every time a user clicks on any item, a record would get inserted into this table. If any other user tries to open that item.. a notification would pop up on his screen that the resource is locked for actioning by XYZ. Futher you will need to create a service which would run say every minute and will remove any record which is older than 15 mins.
PS: Whenever any user has finished taking action on any item.. that row would get deleted from item_lock table.

Good way to determine if someone left a webpage

I am trying to code an app for work where our clients can edit certain fields. When they click edit, the code will lock the data to be editted. And when they click save the data will unlock. But I am having trouble deciding if I can unlock the data when they click elsewhere, go to another page or site, or even close the browser.
What's a good way to decide if the user has left the edit page?
(We are using C# .NET 3.5 and JQuery and a SQL Server 2005 DB).
If you really must use pessimistic locking you could add check in Session_End and unlock all locks that this user set in current session. Use onUserExit jQuery plugin to end session if user closes the browser window or goes on another site, here is the example :
https://stackoverflow.com/a/10481972/351383
You can make use of "onunload" event of html tag. This event is raised
- when Page is closed using X button
- when Page is redirected(In your case user clicks on edits and move on to different link without saving.)
Hope this helps!!
Your question is being understood as "what's a good way to decide if the user has abandoned the edit page without having clicked 'Save' to unlock the field?"
But I am having trouble deciding if I can unlock the data when they click elsewhere, go to another page or site, or even close the browser.
All the scenarios in which someone looks at another page from the same application might mean another window in the same session - perhaps to check something. You don't want that to trigger an unlock because your user could still have a window open in which they can submit the edit.
The other scenarios where the user leaves the page can use onUserExit.
However, you omit from this list the scenario "user goes to lunch leaving webpage open". This is why pessimistic locking is problematic.
Therefore, rephrase the problem as "the user has clicked Edit, but then failed to make the amendment and save within a reasonable time limit".
Basically, your lock should at some point expire.
Upon clicking 'Edit', the save lock kicks in and a timer (5 minutes?) starts, which is also visible on-screen. (If getting these in sync is an issue, make the client-side timer shorter than the server-side one). Your users must make the change and click Save within this time. You could perhaps add an Extend button to extend the time.
The principle is that you need to determine that someone has left it too long, not that someone has left it. You also show to users that having clicked Edit you are expecting them to make an edit some time soon.
You will need to code your system to unlock fields where the lock has expired.
This has the benefit that your countdown will look 'cool' to the sorts of people that request such edit locks.

How to stop loading a page after the request is sent?

I have an ASP.NET (C#) page that has a long load time (like 2 minutes). The user is presented with a little animation and a "please wait" message. If the user accidentally loads this page, they need to wait for it to load.
My question is: Is there a way to stop the page load?
Thank you
If you want to stop the server side processing then its a tricky operation. Generally once a request is made that page is rendering on its own independant of other thigns going on. What you would probably need to do is re-engineer that page to check at regular intervals whether a stop command has been issued and abort whatever it is doing at that point. The stop flag could be put in session and should be cleared out after the stoppage.
You may also need to consider how to properly identify the right one to stop (in case there is more than one running). This could be done by returning a unique ID that can be used in part of a call to the "abort" page.
My approach though rather than this complciated rigmarole is to make efforts to stop the user from making this accident. Possibly make whatever link they are clicking pop up an alert saying "the following page will take several minutes to render, do you wish to continue" and then hopefully you will effectively be aborting the page request before it is even made.
I should note that I've never tried to do this sort of thing before so there may be easier ways to do it but this is how I'd probably think abotu going about the problem.
Try window.stop() in JavaScript.

Categories

Resources