Reputation: 2634
I need to do some audio processing in an MVC 3 application and would like to know the pro's & cons of the different these different background methods. The audio processing as a general rule will be a long running process so I'd just like to make sure IIS is free to handle other requests.
AsyncController & background worker
public ActionResult GetAudioCompleted(byte[] audio)
{
return File(audio, "audio/wav", "mywavfile.wav");
}
public void GetAudioAsync()
{
BackgroundWorker w = new BackgroundWorker();
w.RunWorkerCompleted += (s, e) =>
{
AsyncManager.Parameters["audio"] = e.Result;
AsyncManager.OutstandingOperations.Decrement();
};
w.DoWork += (s, e) =>
{
byte[] b;
using (var ms = new MemoryStream())
{
// Process audio to memory stream
ms.Seek(0, SeekOrigin.Begin);
b = new byte[ms.Length];
ms.Read(b, 0, (int)ms.Length);
e.Result = b;
}
};
AsyncManager.OutstandingOperations.Increment();
w.RunWorkerAsync();
}
AsyncController & Task
public ActionResult GetAudioCompleted(byte[] audio)
{
return File(audio, "audio/wav", "mywavfile.wav");
}
public void GetAudioAsync()
{
AsyncManager.OutstandingOperations.Increment();
var t = Task<byte[]>.Factory.StartNew(() =>
{
byte[] b;
using (var ms = new MemoryStream())
{
// Process audio to memory stream
ms.Seek(0, SeekOrigin.Begin);
b = new byte[ms.Length];
ms.Read(b, 0, (int)ms.Length);
}
return b;
})
.ContinueWith(c =>
{
AsyncManager.Parameters["audio"] = c.Result;
AsyncManager.OutstandingOperations.Decrement();
});
}
Non async controller & Thread
public ActionResult GetaAudio()
{
byte[] b;
using (var ms = new MemoryStream())
{
var t = Thread(() =>
{
// Process audio to memory stream
});
t.Start();
t.Join();
// error checking etc.
ms.Seek(0, SeekOrigin.Begin);
b = new byte[ms.Length];
ms.Read(b, 0, (int)ms.Length);
return File(b, "audio/wav", "mywavfile.wav");
}
}
Questions:
Which approach would seem better to you and why? Any other approaches are welcome.
Upvotes: 1
Views: 633
Reputation: 155250
No. ASP.NET and IIS executes each HTTP request/response on its own thread. Asynchronous programming in ASP.NET is more about doing more work per request (such as executing unrelated SQL queries on separate threads), not about handling threading the request.
I don't know, I'm not too familiar with Tasks.
Yes, and yes.
I would do it like this (psuedocode):
System.Threading.Thread
instance), this means the IIS request/response thread isn't blocked and can return HTML to the client immediately.GET processingJobs
would look up the background thread for job 123 and see if it's complete, if it is not complete then it returns a HTML response saying "your job is being processed, please refresh the page again for updated status", along with a little javascript that refreshes the page every 5-10 seconds.content-disposition:
header.This technique scales up well, or even infinitely if audio processing is handled by a separate process or by a queue system rather than doing them all simultaneously.
A general guideline: if a HTTP request/response cannot be completed within 100ms then do the job in the background and immediately return a status message.
Upvotes: 2