2009-12-26 90 views
0

我正在开发一个项目,并且有大量的电子邮件发送它的一部分,当用户点击按钮时,他/她立即得到“感谢电子邮件已发送”作为响应并且同样的方法正在发射一个异步线程。当Asp.net终止后台线程?

ThreadPool.QueueUserWorkItem(SendEMail, _message); 

当用户点击发送按钮这个线程进行排队,但因为这是默认Background Thread当页面响应结束后,该线程将被终止我所期待的,但它并没有发生,因为当前线程这火这个线程也是一个Background Thread和一个Worker Thread,所以这意味着有一个未完成的前景线程(可能是主线程或工作线程)仍然活着,但我不知道他们什么时候完成,因为他们的完成时间会影响我的后台工作者线程;当最后的前台线程结束时,它会导致进程终止,所以后台线程也是如此。

我应该害怕这个还是Asp.NET可以自动处理它,我有点困惑,因为我已经读了很多关于它的事情,现在一切都混在一起了。

请您澄清一点事情吗?

在此先感谢。

回答

3

对长时间运行的任务使用ThreadPool会对应用程序的性能产生负面影响(因为ASP.NET也使用ThreadPool处理传入的请求)。

如果创建的线程太多,为每个任务手动创建线程也会成为问题。

过去我使用过的一种技术是在启动应用程序时创建一个自定义的ThreadPool,并将该任务排入该ThreadPool。一个简单的自定义ThreadPool可以由一个线程和一个任务队列组成。

1

当您调用QueueUserWorkItem时,将从线程池中提取新线程(如果可用)并在该线程上执行回调函数。如果没有线程可用,则该函数将阻塞,直到线程被释放。一旦完成该方法的执行,该线程将被挂起并返回到池以供进一步重用。您唯一应该担心的是池中的线程也用于处理请求,因此如果您对它们执行冗长的任务,则可能会危及整个系统请求服务能力,因为池中的线程数量有限,并且如果全部他们忙于执行冗长的操作,未来的HTTP请求将排队。作为替代方案,您可以考虑手动创建线程:new Thread(state => { }).Start();

+0

那么前景线程呢?哪一个是前景事件或主要事件,我如何知道它们何时发生? – Tarik 2009-12-26 08:59:48

+0

手动创建线程通常是不被接受的,特别是在ASP.NET应用程序中。如果创建的线程太多,它会显着减慢应用程序的速度。 – 2009-12-26 09:01:14

+0

我不知道我理解你的问题。你能否详述一下你的情况? – 2009-12-26 09:01:15

1

您可以使用MSMQ创建您的电子邮件队列并让单个线程处理队列。

下面的文章可能很有用,因为它适合您的问题域。尽管它不使用MSMQ,但它是使用ASP.net处理计划任务的好帖子。

Simulate a Windows Service using ASP.NET to run scheduled jobs

+0

嗯,它可以提前到我的应用程序,我的使用先进的东西,我相信是有点简单:) – Tarik 2009-12-26 09:20:07

+0

我不会称它为先进的。它有助于解决手头的问题。此外,如果你确实感觉它是高级的,你可以创建一个类型为Queue的队列和队列对象的应用程序级变量,然后让你的线程处理它。它类似于MSMQ并解决了这个目的。但是您需要使线程安全,因为访问单个队列的两个线程可能会产生不可取的效果。 – 2009-12-26 09:25:45

+0

使用MSMQ的好处在于,在发生应用程序崩溃时,您的队列不会丢失。您可以在应用程序重新启动时从最后处理的项目恢复。 – 2009-12-26 09:27:19