如何设置ASP.NET MVC以独立于请求处理上载的数据?

时间:2011-04-26 01:09:49

标签: asp.net asp.net-mvc multithreading threadpool

我刚开始学习ASP.NET MVC。我正在处理的网站要求用户上传通过NHibernate加载到SQL数据库中的XML文件。现在使用一个小的XML文件正常工作,但是一旦我尝试了一个更大的文件,我就开始遇到问题了。

当我上传一个较大的文件时,需要一段时间才能将数据写入数据库,因此在用户端,它们会卡在“等待本地主机......”,直到数据库写入完成并且{{1 action方法返回一个视图。

相反,我想像大多数热门电影上传网站一样设置一些内容,一旦用户上传文件,他们会立即发送到另一个页面,并显示“正在处理您的上传内容”的消息稍后回来“。

我已经做了一些多线程,但我几乎不觉得我知道我在做什么。虽然,刚才我似乎已经按照我想要的方式使用Upload()

使用这样的线程池是解决此问题的最佳方法吗?

这是我的Upload()操作方法。

System.Threading.ThreadPool

这是我的WriteUploadToDb()方法,它在ThreadPool上运行。

public ActionResult Upload(int id)
{
    //check the type of request
    if (Request.RequestType == "GET")
        {
            //get GET show the upload form
            return View();
        }
        else if (Request.RequestType == "POST")
        {
            //if POST process uploaded file data
            if (Request.Files.Count == 1)
            {
                //copy the upload stream into a memory stream
                System.IO.MemoryStream memStream = new System.IO.MemoryStream();
                Request.Files[0].InputStream.CopyTo(memStream);

                //send the the memorystream, id, and username to a new Thread pool work item
                System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(WriteUploadToDb), new WriteUploadToDbData(id, memStream,User.Identity.Name));

                //send the user to a page
                ViewBag.Message = "Your file is being processed. Please come back later...";
                return RedirectToAction("Reports", new { ID = id });
            }
            else
            {
                throw new Exception("Multiple report files uploaded!");
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

取决于您在此处执行此操作的音量。

对于低到适度的音量,启动异步线程来完成工作很好。但是,给定的Web服务器只能处理这么多线程(线程池具有有限但可配置的大小)。

对于大批量应用程序,我更喜欢让Web服务器只处理Web请求并将任何异步处理卸载到另一台服务器。这可以通过例如完成。使用MSMQ或写入另一个服务器选择和处理的日志文件(后者通常用于非常大量的应用程序,因为写入文件是一个非常快速且非常可靠的过程)。

我更喜欢这条路线的原因是我可以扩展以独立于处理异步工作项来处理传入的Web服务/网站请求,从而可以更好地控制扩展。