【问题标题】:How do I continue working on the server after returning a response with ASP.NET? (WebForms and MVC)使用 ASP.NET 返回响应后,如何继续在服务器上工作? (WebForms 和 MVC)
【发布时间】:2008-12-02 20:18:03
【问题描述】:


我有一个需要用户上传照片的应用程序。照片上传到服务器后,应该不会花很长时间,用户应该会收到一个普通 HTML 页面的响应,上面写着“谢谢...bla bla bla...”
现在,在响应被发送回客户端并且他继续他的快乐方式之后,我希望服务器继续处理这张照片。它需要做一些很重并且需要很长时间的事情。但这没关系,因为用户不需要等待任何东西。他可能在不同的页面上。
所以我的问题是,我如何使用 ASP.NET 做到这一点。 我正在编写的应用程序是在 ASP.NET MVC 中,所以我想像

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

但我想这并不是真正的做法。此外,由于有时我使用 ASP.NET WebForms,如何使用 WebForms 来完成。
谢谢!

【问题讨论】:

    标签: asp.net asp.net-mvc


    【解决方案1】:

    我们这样做是针对轻量级日志记录情况:

    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.
    

    它绝不是健壮的。如果您需要保证被处理,您应该考虑使用消息队列。这样,您还可以将处理卸载到单独的机器上,而不会让您的 Web 服务器陷入困境。

    编辑:

    以下内容也有效,并且对您的程序员同事来说可能更明显一些。它本质上是相同的,但显然更快,您无需担心调用 EndInvoke()。

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

    延伸阅读:The Thread Pool and Asynchronous MethodsAsynchronous delegate vs thread pool & threadDoes not calling EndInvoke really cause a memory leak ?

    【讨论】:

    • 你最终可能会出现内存泄漏。应该始终调用 EndInvoke。
    • 也许,但并非总是如此。买者自负。首先从 Rick Strahls blos west-wind.com/WebLog/posts/368975.aspx 那里得到这个想法,当前的想法/测试是,如果您不引用 IAsync 返回值,则不会发生“泄漏”,它会在委托完成后被清理。
    • 也就是说,经过进一步阅读,我正在重新审视这个与 ThreadPool.QueueUserWorkItem .. 两者都使用线程池,虽然后者更快,但两者都可能在负载下破坏服务器,并且可能会采用不同的方法被要求。
    【解决方案2】:

    在我看来,您需要分拆另一个流程来完成您需要做的事情。您甚至可能想构建一个 Windows 服务来处理图像。它可能是一个等待文件出现在某处的应用程序,当它完成时,它可以开始工作,离开 asp.net 线程去处理它的业务。

    【讨论】:

      【解决方案3】:

      我过去做过的一种方法是使用“私有”页面/Web 服务来负责启动处理并侦听对其的调用,这种方法与 Web 模型配合得很好。让一个页面与另一个页面异步对话然后继续执行用户正在执行的任何操作非常容易。

      【讨论】:

        【解决方案4】:

        我不是 ASP.NET 程序员,但您通常执行此操作的方式是在服务器上启动另一个线程,它会在原始线程返回视图并退出时为您执行此后台处理。

        如果你搜索“ASP.NET start Thread”,看看你是否能找到一些东西

        【讨论】:

        • IIS 可以在许多条件下回收进程(并终止该线程)——其中一些是不可预测的。因此,将线程用于与请求/响应无关的后台工作并不是一个好主意。
        【解决方案5】:

        看起来您需要第二个进程来处理额外的处理。您可以让原始页面启动该过程,也可以拥有一个独立的应用程序来轮询文件夹并在照片到达时对其进行处理。这样,您还可以防止对您的网络服务器和工作进程征税。

        【讨论】:

          【解决方案6】:

          我可能会创建一个在服务器上运行的 Windows 服务并使用填充队列来处理照片。所以会改变你的

          //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();
          

          这样做,对照片的实际处理与网站完全分开,并为您节省了到处旋转的线程。

          科林·G

          【讨论】:

            猜你喜欢
            • 2019-09-18
            • 2016-01-13
            • 2020-07-29
            • 1970-01-01
            • 2019-12-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多