How to prevent browser timeouts in ASP.NET?
The scenario:
user uploads a small file or about 100 kB to the ASP.NET 4.0 application with perhaps 1000 units of work. The server then gets to work on the units of work, one at a time. Each unit takes a few seconds to complete due to requesting information from an external service. The results are only saved to the database if all units were completed successfully, using a transaction. Once completed, the user may get a list of what was done.
The problem is that the user does not get the confirmation, instead his browser I think gives up because of a timeout.
Future files are expected to be a few 100 times larger, increasing the problem.
I want to prevent this timeout.
Here are some ideas I had:
- Optimize the code to run faster. This is done and is no longer the problem.
- Run the requests to the external service in parallel.
- Increase the server timeouts a开发者_如何学C little.
- Let the user upload the file and then send him an email with the results later when the file has been processed.
- Somehow make the page refresh and show some progress information to the user while waiting, e.g., 5% complete - done in 10 minutes.
How could I implement this last step, showing progress information and preventing browser timeout?
Other suggestions are welcome.
Thanks,
You need to decouple processing the file from browser response. This is achieved by
- Creating a persistent item (i.e. in database, file, etc) in a queue so that it is fault tolerant
- return success result to browser
- Create a queue worker to asynchronously process your queue.
You put the data uploaded into a queue in your database. Then, you have an asynchronous process (example Windows Service) to pull items from your queue and process them. You can update your DB with progress of each operation, and when full completed, remove the item from the queue and update your other tables.
For progress, the user can then query the queue table for the status of his upload.
An easy trick is to write a piece of javacsript to repeatedly request something from the current page. If you use a request action of HEAD then the server will only respond with a minimal amount of information each time.
Something like:
<script src="/js/jquery-1.3.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function(){
setTimeout("callserver()",6000);
});
function callserver() {
var remoteURL = '/yourpage.aspx';
$.get(remoteURL, function(data) { setTimeout("callserver()",6000); });
}
</script>
精彩评论