views:

97

answers:

6

I have a ASP.NET website in which a user makes a request. Every request kicks off a long process that may take several minutes (worst case of 20 mins). At the end of the request a file is created for the user to download.

Currently, I have this request kick off the process asynchronously (using Async pages) but I am getting time out errors. I suspect my approach is flawed. To make this process scalable, my next guess is to have a windows service that executes the long running process. When a user makes a request, I add the request details in a database table. The Win Service picks it up and processes it. In the meantime, the user is redirected to a page that asks them to wait while the file is being created.

Would this be the ideal approach? If so, do I have to refresh the page every x minutes to check if the windows service has completed the processing?

+3  A: 

See my related twin question here (in Java though)

I guess Windows has a Message Que service as well (Actually I remember there is)

This is exactly what a MQ is for...

Ehrann Mehdan
yes, this is an excellent use for a MQ
dan
That also might be a use case for a WCF service with an MSMQ binding.
0xA3
I'd tend to disagree with this option. I think using MQ's give very little benefit and a lot of extra overhead.
Clarence Klopfstein
+1  A: 

You can either use a Windows service or a background thread.

A Windows service has the advantage that you could potentially run more than one of them on remote machines ("compute servers").

Passing messages to a background thread can be done using in-memory queues. With a service, you should use a more formal message passing system, such as SQL Server's Service Broker. Service Broker also handles persistence and provides some clean mechanisms for scaling.

In case it helps, I cover Service Broker and background threads in my book, including code examples: Ultra-Fast ASP.NET.

RickNZ
A: 

What I have had to do in the past is upon the users action that kicked off the long process, I'd write a 'job' to the database, with a status. The website can then show that status to the user.

Then you have a service running on the server that monitors that database table and do the long action, updating the status accordingly. The service would then either create the file or email it to the user.

Finally that service would also have to take into account how long you want that file to reside on your server. So if you wanted to delete it after so much time, you'd have to have a status of expired.

In short, yes I think your approach is flawed.

Clarence Klopfstein
How does the service notify the UI that the process has been completed? Or does the UI need to poll the database and refresh the page?
It can poll it on page load at the most basic level or, as Krip specified, use some fancy AJAX to poll the database ever n seconds or so.
Clarence Klopfstein
A: 

Any task which takes 20 mins should be taken out of ASP.NET process and off loaded else where in the domain. Here are a few options which I use in my production enviornment

  1. If you have access to the DB Server, then create a table there where users can queue jobs with parameters along with their email address. Then create a DTS (SSIS SQL Server 2005-2008) which will check for jobs every 5-10 mins, execute and email the results. The users are already waiting 20 mins.

  2. Create a windows service which will poll a job queue (like above), execute and then email the users the results.

Both ways require a job queue, however, the users just submit a job and move on. The result is sent to their mailbox, or even as a binary document stored in the DB.

Saif Khan
A: 

I vote for the windows service approach, but also agree with Clarence Klopfstein's comment to show job status to user on a web page. Page can show a list of all jobs user has rights to see. If the process can take up to 20 minutes keep updating status so the user sees progress. You can have the page auto-refresh with some JavaScript. Show a link to the file when the job is done.

If you want to get crazy, write some AJAX that pops up a piece of toast when the file is generated - include a link to the file in the toast. Include that JavaScript segment on every page in the site so the user gets the notification no matter where he is.

-Krip

Krip
Any help in creating a AJAX way of autopolling to check the status will be really appreciated. Thanks
A: 

This problem is a perfect candidate for a Message Queue, you should have a Windows Service which hosts a WCF service that uses MSMQ as a transport, the MSMQ will guarantee delivery of message and also it will guarantee that no messages get lost in case of service failure or machine restarts.

bashmohandes