MVC 3后台处理的优缺点

时间:2013-03-07 02:45:17

标签: asp.net-mvc-3 task-parallel-library backgroundworker

我需要在MVC 3应用程序中进行一些音频处理,并希望了解专业版和这些不同背景方法的不同之处。 作为一般规则,音频处理将是一个长期运行的过程,所以我只想确保IIS可以自由处理其他请求。

  1. AsyncController&后台工作者

    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();            
    }
    
  2. AsyncController&任务

    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();
            });          
    }
    
  3. 非异步控制器&amp;螺纹

    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");
        }
    }
    
  4. 问题:

    1. 建议将BackgroundWorkers用于Web应用程序吗?
    2. 如果我使用任务,这个后台线程是否使用IIS线程池中的一个,(可能否定了这种方法的一个好处,因为线程未被释放用于请求处理)?
    3. 使用System.Threading.Thread - 此线程是否使用IIS线程池中的一个。 t.Join()是否阻止当前的IIS线程?
    4. 哪种方法对您来说似乎更好?为什么?欢迎任何其他方法。

1 个答案:

答案 0 :(得分:2)

  1. 没有。 ASP.NET和IIS在其自己的线程上执行每个HTTP请求/响应。 ASP.NET中的异步编程更多的是为每个请求执行更多工作(例如在不同的线程上执行不相关的SQL查询),而不是处理线程化请求。

  2. 我不知道,我对任务不太熟悉。

  3. 是的,是的。

  4. 我会这样做(伪代码):

    1. 我将处理该文件然后在后台线程中处理(使用简单的System.Threading.Thread实例),这意味着IIS请求/响应线程未被阻止并且可以将HTML返回给客户端立即
    2. 我会在此文件处理作业的某处存储令牌或引用。然后我将303重定向返回到“/ processingJobs / job123”(其中job123是作业ID)。
    3. GET processingJobs的actionHandler将查找作业123的后台线程并查看它是否完整,如果未完成则会返回HTML响应,说明“您的作业正在处理中,请再次刷新页面更新状态“,以及每隔5-10秒刷新一次页面的小javascript。
    4. 如果作业已完成,则返回带有content-disposition:标题的已处理音频文件。
    5. 如果音频处理由单独的进程或队列系统处理而不是同时进行,则此技术可以很好地扩展,甚至无限扩展。

      一般准则:如果在100毫秒内无法完成HTTP请求/响应,则在后台执行该作业并立即返回状态消息。