ASP.NET中的BackgroundWorker线程
是否可以在以下情况下使用ASP.NET 2.0中的BackGroundWorker线程,以便浏览器端的用户不必等待很长时间?
设想
- 浏览器请求页面,例如SendEmails.aspx
- SendEmails.aspx页创建一个BackgroundWorker线程,并为该线程提供足够的上下文来创建和发送电子邮件。
- 浏览器从ComposeAndSendEmails.aspx接收响应,说正在发送电子邮件。
- 同时,后台线程参与了创建和发送电子邮件的过程,这可能需要花费大量时间才能完成。
我主要关心的是在ASP.NET workerprocess线程池线程已久的情况下,保持BackgroundWorker线程运行,尝试发送50条电子邮件。
解决方案
回答
ThreadPool.QueueUserWorkItem(delegateThatSendsEmails)
或者在System.Net.Mail.SmtpServer上使用SendAsync方法。
我们希望将发送电子邮件的代码放在另一个线程上,因为这将立即返回用户,并且将进行处理(无论花费多长时间)。
回答
有可能的。从页面异步启动新线程后,页面请求将继续进行,并将页面发送回用户。异步线程将继续在服务器上运行,但不再有权访问该会话。
如果必须显示任务进度,请考虑一些Ajax技术。
回答
如果我们不想使用AJAX库,或者电子邮件处理时间真的很长,并且会使标准的AJAX请求超时,则可以使用.net 1.1天内的"老方法" AsynchronousPostBack方法。
本质上,我们要做的就是让"提交"按钮以异步状态开始电子邮件处理,同时将用户带到中间页面。这样做的好处是我们可以根据需要刷新中间页面,而不必担心达到标准超时。
当后台进程完成时,它将在数据库/应用程序变量/任何内容中放置一个"完成"标志。当中间页面刷新自身时,它将检测到此标志并自动将用户重定向到"完成"页面。
同样,AJAX可以解决所有这些问题,但是如果由于某种原因我们必须在网络上进行非常密集或者及时的处理,则此解决方案将为我们服务。我在这里找到了不错的教程,并且还有更多的教程。
当我们在与第三方应用程序接口的" Web Check-in"类型应用程序上工作时,我必须使用这样的过程,并且它们的导入API太慢了。
编辑:嘎!诅咒你古兹拉和你类似神的打字能力8 ^ D。
回答
我们不应该从ASP.NET页进行任何线程化。当工作进程回收时,任何长时间运行的线程都有被杀死的危险。我们无法预测何时会发生这种情况。任何长时间运行的进程都需要由Windows服务处理。例如,我们可以通过在MSMQ中放置一条消息来启动这些过程。
回答
在这种情况下,我们需要使用Asynchronous Pages,这是ASP.NET 2.0中添加的功能。
Asynchronous pages offer a neat solution to the problems caused by I/O-bound requests. Page processing begins on a thread-pool thread, but that thread is returned to the thread pool once an asynchronous I/O operation begins in response to a signal from ASP.NET. When the operation completes, ASP.NET grabs another thread from the thread pool and finishes processing the request. Scalability increases because thread-pool threads are used more efficiently. Threads that would otherwise be stuck waiting for I/O to complete can now be used to service other requests. The direct beneficiaries are requests that don't perform lengthy I/O operations and can therefore get in and out of the pipeline quickly. Long waits to get into the pipeline have a disproportionately negative impact on the performance of such requests.
http://msdn.microsoft.com/zh-CN/magazine/cc163725.aspx
回答
如果要在ASP页中使用多头处理,则可以使用以下简单的线程模型:
{ System.Threading.Thread _thread = new Thread(new ThreadStart(Activity_DoWork)); _thred.Start(); } Activity_DoWork() { /*Do some things... }
此方法是使用ASP页面的正确方法。当BackgroundWorker完成时,带有BackgroundWorker的ASP页将不会启动。