views:

213

answers:

6

Hi.
I have an application where I need the user to upload a photo. After the photo is uploaded to the server, which shouldn't take very long, the user should get back a response that's a regular HTML page saying "thanks...bla bla bla..."
Now, after the the response is sent back to the client and he goes on his merry way, I want the server to continue to work on this photo. It needs to do something that's heavy and would take a long time. But this is okay because the user isn't waiting for anything. He's probably in a different page.
So my question is, how do I do this with ASP.NET. The application I'm writing is in ASP.NET MVC so I'm imagining something like

//save the photo on the server
//and send viewdata saying "thanks..."
return View();
//keep doing heavy processing on the photo

But I guess this isn't really how it's done. Also, since sometimes I work with ASP.NET WebForms, how is this done with WebForms as well.
Thank you!

+1  A: 

It seems to me like you need to spin off another process to do what you need to do. You might even want to build a windows service to handle the processing of the image. It could be an app that sits around waiting for a file to appear somewhere, and when it does it can go to work leaving the asp.net thread to go about its business.

Chris
A: 

I'm no ASP.NET programmer, but the way you generally do this is to start another Thread on the server, which does this background processing for you while the originating Thread returns the View and exits.

See if you can find something if you search for "ASP.NET start Thread"

Rolf
IIS can recycle the process (and kill that thread) upon many conditions - some of which are not predictable. So using threads for a background work not related to a request/response is not a good idea.
Sunny
A: 

It looks like you would need to have a 2nd process that takes care of the extra processing. You can either have your original page kick off the process or you could have a stand alone application that polls a folder and process them as the photos arrive. This way you also prevent taxing your web server and worker process.

Victor
A: 

One way I've done it in the past, which plays somewhat nicely with the web model, is to have a "private" page/web service that is responsible for kicking off processing and listens for a call to it. It's pretty easy to have a page asynchronously talk to another page and then continue with whatever the user is doing.

Joel Meador
+2  A: 

We do this for a lightweight logging situation:

Action<object> d = delegate(object val)
{
    // in this anonymous delegate, write code that you want to run
    ProcessDataAndLog();
};

d.BeginInvoke(null, null, null); // this spins off the method asynchronously.

It's by no means robust. If you need a guarantee of being processed you should consider a message queue. That way you can also offload processing to a separate machine and not bog down your web server.

EDIT:

The following also works, and is perhaps a little more obvious to your fellow coder. It's essentially the same, but apparently faster and you don't need to worry about calling EndInvoke().

System.Threading.ThreadPool.QueueUserWorkItem(
    delegate(object state)
    {
        // in this anonymous delegate, write code that you want to run
        ProcessDataAndLog();
    });

Further Reading: The Thread Pool and Asynchronous Methods and Asynchronous delegate vs thread pool & thread and Does not calling EndInvoke really cause a memory leak ?

Robert Paulson
And you end up with a possible memory leak. One should always call EndInvoke.
leppie
Maybe, but not always. Caveat Emptor. First picked up the idea from Rick Strahls blos http://www.west-wind.com/WebLog/posts/368975.aspx Current thinking / testing is that no 'leaks' occur if you don't reference the IAsync return value, it gets cleaned up after the delegate is finished.
Robert Paulson
Saying that, upon further reading, I am revisiting this versus ThreadPool.QueueUserWorkItem .. both use the thread pool and while the latter is quicker, both may thrash the server under load, and a different approach may be called for.
Robert Paulson
A: 

I would probably create a windows service that runs on the server and use a fill a queue to process the photo. so would change your

//save the photo on the server
//Add referance in queue (possibly in database to http post that the windows service monitors with details of path to the file, output path, transformation etc.)
//and send viewdata saying "thanks..."
return View();

Doing it this way the actual processing to the photo is completely separate from the web site and save you spinning threads all over the place.

Colin G

Colin G