我正在处理一个项目,并且有大量电子邮件发送部分内容,当用户点击该按钮时,他/她立即收到“感谢已发送的电子邮件”作为响应并且相同方法也在触发异步线程。
ThreadPool.QueueUserWorkItem(SendEMail, _message);
当用户点击发送按钮时,此线程排队但由于这是默认的Background Thread
我期待页面响应结束时,此线程将被终止,但它没有发生,因为当前线程触发这个线程也是一个Background Thread
和一个Worker Thread
,这意味着有一个未完成的前台线程(可能是MainThread或工作线程)还活着但是我不知道不知道他们什么时候完成,因为他们的完成时间将影响我的后台工作者线程;当最后一个前台线程结束时,它会导致进程终止,后台线程也是如此。
我是否应该害怕这一点,或者Asp.NET可以自动处理它,我有点困惑,因为我已经阅读了很多关于它的事情,现在一切都搞砸了。
你可以请一点澄清一下吗?提前致谢。
答案 0 :(得分:3)
将ThreadPool用于长时间运行的任务会对应用程序的性能产生负面影响(因为ASP.NET也使用ThreadPool来处理传入的请求)。
如果创建了太多线程,则为每个任务手动创建线程也会成为问题。
我过去使用的一种技术是在启动应用程序时创建自定义ThreadPool,并在该ThreadPool上排队任务。一个简单的自定义ThreadPool可以包含一个Thread和一个Queue of tasks。
答案 1 :(得分:1)
当你调用QueueUserWorkItem时,如果可用,将从线程池中抽取一个新线程,并在该线程上执行回调函数。如果没有可用的线程,该函数将阻塞,直到释放一个线程。一旦完成方法的执行,线程将被挂起并返回到池中以供进一步重用。您唯一关心的问题应该是来自池中的线程也用于服务请求,因此如果您对它们执行冗长的任务,您可能会危及整个系统请求服务功能,因为池中的线程数量有限且所有线程都是他们忙于执行冗长的操作,未来的HTTP请求将排队。作为替代方案,您可以考虑手动创建线程:new Thread(state => { }).Start();
答案 2 :(得分:1)
您可以使用MSMQ创建电子邮件队列,并让一个线程处理队列。
以下帖子可能很有用,因为它适合您的问题域。虽然它不使用MSMQ,但是使用ASP.net处理预定任务是一个很好的帖子。
Simulate a Windows Service using ASP.NET to run scheduled jobs