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

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.

Related

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

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.

Disable a button for t minutes

I want to disable a button for twenty minutes this should remain disabled even if the application is restarted.
I was thinking doing this by reading and storing the time when the button is pressed, then read the system time every minute and when the elapsed time be 20 or more minutes, enable the button.
I think this would allow me to restore the time when the button was pressed if the application is restarted; and then check for the elapsed time.
Do you think this is a good idea?
Any other option?
Since you want this setting to work even if the application restarts, this won't be possible unless you involve an external agent. A few options that you might try involve:
Read current Internet time from http://time.windows.com or nist etc and store it somewhere (registry or local file). Use a timer within your application that keeps fetching latest time from the Internet and compares it to the save value. This post allows you to read current Internet time using both HTTP and TCP port 13.
Use Windows scheduled tasks. Set a bool flag somewhere (file/registry again) and ask the scheduled task to clear the flag after 20 minutes. This post should get you going with creating scheduled tasks.
Create a Windows service that keeps running in the background that you could call to set the flag and the length of time for which this flag should remain set. The service should run an internal Timer (and should not rely on system time) to keep track of "ticks". After the specified time has elapsed, the service should clear he flag.
Here is what I am thinking,
When the application starts, disable or hide the button
Set the time stamp when disabling/hiding and store in a database table or a file.
Now read every minute or every five minutes - whichever is convenient to see if 20 minutes have elapsed.
IF 20 minutes have passed, remove the entry from table or file.
And if the application crashes or restarts before setting the time stamp:
1.While setting the time stamp, make sure that the table or file is empty. If not, enable the timer - the time stamp is there.
Well if I were you, I'd basically disable the button
and then start a timer, each minuite, the program should write the time left to a file as well as the current time ( you can also decrypt this file, so that users can't change it )
Now when the program restarts, it should read this file, and start a timer according to the written time in the fil :)
If you want the timer to work even when the program is closed, then you might check this out (File.GetLastAccessTime)
Basically, you should compare the (current time) that has been written to the fil, with the last access time, and make a function to get the time left :)
This might not be a perfect solution, but it will work fine ( I guess )
Kind Regards :)

How to dynamically run process in asp.net

I am designing a website and it uses Windows Forms (in Visual Studio 10) in which for example i have five-six URLs. Now i am displaying them on home page of my website xyz.com
What i want is, i want to calculate total no. of tweets for all links and display links based on no. of times they are being tweeted/retweeted.
for a url we can calculate no. of tweet using twitter api http://urls.api.twitter.com/1/urls/count.json?url=YourURL
I know all the stuff like receiving JSON values in a string and parsing json to retrieve tweet counts and then compare and display links based on the priority etc.
What i have been using till now it is initiating all the process using a Click_Button.
But i want to know how can i automate this all for each 10 minutes. Its like a end user can see urls priority with just refreshing the page.
One way to do this is to run a scheduled task ever 10 mins which interacts with the DB. The web application also interacts with the DB and thus the two systems are distinct.
Side note: it is strongly recommended to use only console applications as scheduled tasks. If you make a windows form application will will have some issues.
As Kieren Johnstone has pointed out in another answer the best way to do this would be to write a windows service.
I still recommend the solution as described above as a first step since it is easy to debug and test.
Additionally, give some serious consideration to logging and error reporting -- with background tasks you can never know to much about what the heck it was doing when it broke.
If timing itself is not important (it doesn't have to be 10 minutes precisely), I would suggest binding to any event that fires when users use your application. No point in calculating anything if noone is using it :-)
So you could use a login, or page load, or whatever happens at an interval roughly like the interval you wish to achieve.
You can always store a DateTime variable somewhere that you can check to see when the calculation was last made. Something like:
public void MyEventHasFired()
{
DateTime dateLastProcessed = ... //Database? Session data? Anything goes.
if(dateLastProcessed < DateTime.Now.AddMinutes(-10))
{
//calculate
...
dateLastProcessed = DateTime.Now;
}
}
The best solution is definitely a Windows Service. It can be started, stopped and managed well, it's easy to log, maintain..
Scheduled Tasks are very prone to problems. At least in a Windows Service you can configure it to start automatically, re-start if there's a problem, you can control the timing yourself in the code, and catch/handle exceptions as you wish.
The best scheduler i know is Quartz.net
It'is not simple to use but it works great.
You can find an example with asp.net there http://blogs.planetcloud.co.uk/mygreatdiscovery/post/ASPNET-Scheduled-Tasks-with-QuartzNET.aspx
Anyway i agree with Kieren Johnstone: you should use a windows service

Directions and Opinions on Creating Update System for the Application

I just try to figure out a good solution on designing the update process for a windows form application i created. I think of a button inside the app for manual checking of an update and checking when starting the app. Only I'm not familiar with technics. I though to have the update setup file in a FTP Server and checking the server for an update with a txt file in there with filename and version info. When app is finished downloading the update, closing and starting the update setup file.
Any suggestions, opinions on the subject?
Application updates these days are one of those necessary evils. Thinking of applications that update automatically, I tend to group them into two categories:
Clean updating, once a month or less often, a speedy update without a lot of nagging or clicking. And definitely no sneaky software included like toolbars and desktop search programs... Firefox tends to be "nice" about updates, though its addons can be naggy.
The other group nags constantly, requires a lot of button clicks or that you reboot, takes a long time to 'unpack' (Adobe Acrobat, looking at you), changes settings against your wishes (Java), or is just generally unpleasant.
With those points in mind, design your automatic update to be as user-friendly as possible, and plan on your users sometimes wanting to skip the update (unless it is critical to operation).
At my company we have a small application that requires updates, but also must function in a very time-sensitive environment. To facilitate updates, we have it do the following:
At startup, a text file is checked on an internal URL (this could be an HTTP or FTP call). The version number is compared to the contents of the file.
If the software is up to date, nothing more is done. If not, a dialog is presented informing the user that the application must perform an update. (In our case there is no option to cancel or wait, but I highly recommend it if you can.)
A setup file is downloaded from the same site, and launched via Process.Start command, with some switches to perform an unattended install/update.
The application is launched after installation and the interruption to user is minimal.
Some things you may want to do differently:
If not checking for updates at startup, provide an option to schedule update checking or manually perform an update check from (for example) a Help menu.
If possible allow the user to cancel or delay an update; there's nothing more frustrating than trying to get work done with a popup dialog asking you to perform an update every few minutes.
Make sure you test your install packages or patches before deployment! (Voice of experience!)
Use ClickOnce http://msdn.microsoft.com/en-us/library/t71a733d%28VS.80%29.aspx
http://www.15seconds.com/issue/041229.htm
Kind regards.

Handling long page execution times in ASP.NET

I'm working on a web application import program. Currently an admin user can upload a formatted csv file that my page will parse. I'm experiencing an execution duration issue as each line pertains to a file that has to be saved to Scribd, S3, as well as some internal processing.
What would you guys recommend for improving execution time? Since this is an admin only page, I doubt it would get run more than once a week, so my hope is to get it out the door asap.
I've looked some at the Async="true" flag, but I wasn't sure if that was the direction I wanted to go, or if I should look more that a windows server.
Two options come to mind:
Threads: In your code setup a collection of threads, join them and then have each one process a single file. Once all the threads complete you'll be able to return the page. This will increase your turn around time, but could still leave something to be desired on page returns
Queue: Have the user submit the csv file and provide a GUID/Hash/Whatever ID where the admin could then go to the "status" page, input their ID and check the details of their job. This solution will provide a quick feedback to the user and allow them to keep track of the results without having to wait around.
A quick and dirty option might be to set Page.Server.ScriptTimeout to a really high value on that page. (I think it maxes at Int.MaxValue).
Probably advisable to block the submit button after its been clicked, and inform the user that they may want to go make a coffee.
I'd suggest using AJAX to have an internal post back occur that would handle the asynchronous processing. You can periodically poll the state, and prevent your master page from having the "processing" wheel constantly churning on the page for the lengthy process.
I have a web page that takes a long time to process a mailing list so I kick it off in it's own thread. When the process is done, a report can be seen from another link on the result page. I have a runable MailSender class. The ASPX script has a bit in it that looks like this:
// prep the MailSender
MailSender ms = new MailSender(people, Subject, FileName....);
if (SendAsync) {
ThreadStart ts = new ThreadStart(ms.run);
Thread WorkerThread = new Thread(ts);
WorkerThread.Start();
} else {
ms.run();
}
If you want to speed your code up, try to break it into parallelizable pieces if you can and write a class for each piece. You could then kick off a new thread for each bit and monitor the status somewhere so the user can be informed when to come back to the results. You said that each line of your input would generate it's own output file. Sounds like a great candidate for multi-threading. Won't speed things up much if you don't have multi-cores availabe on the server though.
One problem with this whole scheme is that server restarts or application pool recycling will kill your long running process. This can be a problem if you threads are going to run for an hour or two.
As external factors are involved in the processing time, you need to consider if performance improvements would affect "actual" performance, if most of the time is in processing it and sending it to the thirdparty (ie Scribd,S3), then making improvements on your end might not have a huge affect and might increase the complexity for a simple task.
What I would do is have the aspx page only doing what aspx does best; ie handling the user interface part only (ie the upload), so once the upload is complete as far as the user is concerned their part is done. You could implement a progress indicator using AJAX to make it nicer but as its an admin section I wouldnt bother with the niceties,
Then have simple console application sheduled to fire at specific intervals, or a windows service watching a directory (depending on how timecritical the updates are), once the app runs as it is in the back ground and does not require user interaction, time is not a critical factor (ie you dont have a user waiting for context to be returned)..
it will appear to the user that things are very snappy (ie the time it takes to upload the file) and you are keeping needless complexity out of your solution.
I think the simplest solution to what you want is to use asynchronous pages in ASP.NET. Is there any particular reason why you don't want to go that route?
I can think of an alternative, which is to have some background process (like a process triggered by a scheduled task in Windows, or a Windows service) that will look at a queue of waiting jobs (say, from a database table) and process those jobs. This way you will have to upload that CSV somewhere and insert a db record so that the background process will see that CSV and use it when it comes around. But to me it seems like more work, so I'd rather use asynchronous pages :)
Here's a nice tutorial on ASP.NET asynchronous pages

Categories

Resources