Currently I am working on a project where a web page will start a 3 hour data transfer process through the use of a web service. Basically a list of Id's are used to tell the web service to transfer an data object from one database to another.
When I start the process, I would like to allow the user to remain in control. He must be able to see how far the current process is, and be able press a cancel button to stop the data transfer. All this is run from an ASPX web page.
I have discovered that trying to run the process asynchronous does not allow me to update the user interface as I had hoped. Only when the entire process is finished Another problem I might face is that since the process takes a lot of time, the server objects might get refreshed at some point, which could cause me to lose my progress.
I am currently at the point where I am deciding whether or not to use the web server to process the data transfer. If I am, my current solution is to use tasks to run the process asynchronously, and use client side web calls (to the aspx page) to update the client interface. I am also implementing the IRegisteredObject interface for my work object. IRegisteredObject explanation
Any idea on how to best tackle this problem is most welcome. I really want to know if I'm heading in the right direction.
My suggestion would be for you to create a WCF service, which is not hosted within ASP.NET and to make your ASP.NET application call that service to trigger the long running job that performs the data transfer. Meanwhile your ASP.NET app notifies the user that it has triggered the job and you can expose other endpoints on your service which the ASP.NET application can query through a user request in order to extract and report progress.
The web server will only run one page at a time for each user, so if you want to communicate with the browser while the process is running, you can't run the progress from a request. You need to start it as an independent background thread, so that you can finish the request that started the process.
After that you can send requests to the server either to do polling for status of the process, or to control the process.
If possible you should run the process entirely outside of IIS, for example as a console application. That way you only have to keep track of the fact that there is a process running in the web application, for example putting that in a database so that it survives IIS recycling.
Related
I'm wondering what the preferred architecture would be for the following situation:
I'm required to have a .NET application that will perform batch upload of multiple data files concurrently to a SQL Server. This will be invoked from a WPF application which will allow the user to select the files and the destination tables, as well as reporting on the individual progress for each upload (including error messages). I have absolutely no problem writing the code for any of this. However, there is a requirement that the user is able to close the WPF application altogether and for the upload process to continue. Further, if the user restarts the WPF application from the same machine, it should be able to get a handle on the existing uploads and report on the status as if the program were never closed.
My question is what are the ways of achieving this and which would seem the most standard/suitable?
I've considered simply not actually closing the WPF application but hiding all the windows, but this seems a cheat. Would it be best to create a WCF service on the server where the upload is taking place and simply upload the file? I don't think I can do that and report progress % etc though. What about a locally-running Windows Service, can I achieve a similar effect? Should I be thinking of MemoryMappedFiles?
Appreciate all your thoughts.
Because you are talking about long-running task, I would use local Windows Service communicating with your WPF application through MSMQ. For example, each file to upload can be represented by one MSMQ message. Your WPF application will be putting messages into queue and Windows Service, periodically and without any impact if WPF is running or not, should take it from queue and process. This will provide simple and reliable channel of providing tasks (uploads).
To provide internal status of the Windows Service to its clients (your WPF application), I would host inside it a WCF endpoint with simple service that is telling, for example, about progress.
I am coding an ASP.NET MVC 3 app. When a user logs in I need to check a remote system and get the latest data for that user from the system. This task will take approx 15 seconds.
The user should be able to enter my app straight after their login (not have to wait for 15s for the remote call!). When the remote call completes the users local information will be updated.
I was thinking of using a thread to do this, creating it after they have logged in and letting it run its course. However, after reading around, I am concerned about recycling etc when working with threads in MVC. I would use an async controller, but I dont need to feedback to the user the state of this background process. Am I right to be concerned about threads, even if they are short-lived?
"...concerned about recycling..."
"...don't need to feedback to the user the state..."
"...short-lived..."
3 reasons why you should be using ThreadPool.QueueUserWorkItem.
Do not use "threads" in an web app. Let the server handle this by using "async" calls.
Otherwise you would have to setup a threadpool and que the slow request.
I have an ASP.NET web app providing access to a database on the server. What I need is a way to run code in the background on a given schedule that auto-updates the server database from another source.
I know how to do this in a windows app by adding a timer, linking up a function to the timer tick event and starting the timer. I do not know how to do this in a web app.
Is there a start-up event for a web app or somewhere where I can start this background process regardless of whatever any users are doing on the site?
You should not do this in an ASP.NET website - this is a major no-no. You are correct in thinking to use a timer on a background .exe. You should look into creating either a Windows Task (a console .exe executed by the server task timer), or a Windows Service. I would suggest the Windows Service as that is standard practice.
If you have access to the computer hosting your site I would write a little app that was run from the Task Scheduler.
The web server is not meant to handle long-running background tasks. It's the wrong tool.
If you dont have access to the hosting computer then I would suggest building some kind of interface whereby another computer rebuilt the database and uploaded it. I'm using the terms "interface" and "upload" in the loosest, broadest sense - apply your own definition.
I was searching for a solution myself couple of months ago, and even though I haven't found enough time to try it so far, I guess I can share the link with you. Maybe you'll find it helpful.
If yes, please, let me know here.
http://quartznet.sourceforge.net/
How to use Quartz.net with ASP.NET
you can use Windows Service or use Timer Control (In the Ajax Category)
Or
As other answers have stated, doing this full function - updating a database and scheduling it as an ASP.NET app is using the wrong tool for the job.
ASP.NET can be used to update a database - that's perfectly valid. Where it breaks down is in the timer. ASP.NET apps aren't meant to be long-running, which is necessary for the timer to work.
If you can do it, I'd strongly suggest using the approach others have suggested - a Windows Service or a Scheduled Task.
However, if you have no access to the actual server, other than to post ASP.NET code - you can't install a service and you can't set up a Windows app to run on a scheduled basis, here's an out-of-the box idea.
Set up a web service or ASPX page that does the update, and then call that page from a scheduled task on a machine you DO control.
So if this was at http://www.someserver.net/updatedb.aspx, there's no reason you can't set a scheduled task on your own PC to call that URL.
I'd consider this a last-ditch solution to be used only if you can't do one of the other options.
The global.asax.cs file has a method that is fired when your application starts: Application_Start. You can hook up your timer method in that event. Just beware, depending on how IIS configured, your app pool may shutdown. For example, if no one hits the site in 20 minutes for example. Just make sure if you HAVE to have this run every X minutes that you have IIS configured to ALWAYS be running and start your app. This is harder than it sounds. In the end, you may want to go with a regular windows scheduled task.
I am trying here to find a solution to control a process I launch via webforms.
I know it is quite easy to start-stop it using System.Diagnostics.Process class.
What I am trying to achieve is to send data to the process (a terraria server). Basically the server itself when it is launched correctly you can write inside it some commands like kick/ban/save/exit etc.
I'd like to write those commands but remote controlled via a webforms application.
The nearest solution I've thinked would have been to call the server via a daemon I would write that would work as gateway between the webforms commands and the server application. Is that the right way to do things ? Or is there any easier way to do it ?
Are you perhaps looking for the BackgroundWorker class that was introduced in .Net 3.5?
To execute a time-consuming operation in the background, you create a BackgroundWorker, and then listen for events that reportt the progress of your operation and signal when your operation is finished. It executes on a separate thread.
The MSDN site has some examples that might help you figure out if this is for you.
Or you could just use a web service or WCF, couldn't you? You can either host the web service on a web server or as a Windows service.
You can probably start the process on application start and keep a reference to it in a static variable. You'll also need to attach to the OutputDataReceived event so you can record any data the process sends to its StandardOutput stream.
The idea is that the process will be running on the server and the web application will be silently recording any information it sends. When a request comes the buffer will be sent to the user and cleared.
The user can also send commands which the web application will forward to the process through its StandardInput stream.
I haven't tried it but it could possibly work. You will also need to consider what will happen if the application pool recycles. For best results I think you should disable autorecycling.
Yes that is the best way, make windows service that will control and monitor the process and into that windows service build API for a ASP.NET (webforms) application.
ASP.NET application can automatically refresh page (via javascript or meta refresh tag) and get new status from windows service that is controling your process, and event better you can build javascript application and get new status data and send commands with ajax, so there will be no need for whole page refresh.
I have already opened a webpage in Firefox which is actually running through the apache web server on the same machine. And I have C# application running on the same machine.
Now I want to refresh/inform my already open web page that C# has finished processing.
I have seen the threads all over the web and also some similar threads on Stackoverflow but did not find solution.
Any idea how to solve this?
In details: C# Application is transferring images from external storage. Web page (http://127.0.0.1/mypage.php) is looking for the images periodically, but never know that all images are transferred or not so that it can process these images to do some more work.
In this scenario, we want to tell our web page (which is already running in firefox) all data transferred and now you can refresh to process data.
Two steps: Let the server communicate that C# is done, and have the web page react to it
You somehow need to expose the fact that the C# program has finished to the web. If you also have an IIS running, this could be done via a URL served by IIS directly that returns a value indicating whether C# is still running or not. If you don't, you can write to a file, database or whatever and have a script on your Apache server that checks for this value. Whatever you choose, you want something like www.myserver.com/are_you_finished.[php, aspx, whatever] that returns 1 or 0
Then, you can build JavaScript script in your client page that periodically checks this URL and reacts as soon as the value is 1. This would be a typical AJAX call, ie you need to play with XmlHttpRequest. This could be elaborated much further, but maybe you first say if that's what you have in mind, and I also think there's a lot of good documentation on how to do this on here.
You can include a Internet Explorer control in ouyr appliacation. This way you can control which page is displayed and you can call refresh and whatever you want.
Another way is to include a meta refresh tag in the html page so it periodically looks for updates and refreshes ifself.
I see no way to remote control firefox. The only thing i could think of is remember the process id when you start firefox, and the you kill the process and start a new window, but I consider this bad style.