我有一个应用程序,其中一个动作触发了许多电子邮件发送出去。电子邮件的数量是可变的,每个操作可以是10到1,000 。
我不希望应用程序在发送电子邮件时挂起(从而使用户烦恼)并希望在后台发送它们。
我过去没有使用过Threads,这就是我需要你帮助的原因。你会手动创建线程还是使用ThreadPool的好例子?我希望此任务具有低优先级并尽可能少地使用资源,因为即使电子邮件迟到1小时我也不介意。
感谢您的帮助
马尔科
答案 0 :(得分:3)
说实话,ASP.NET中的线程并不是一个好主意。当请求结束并回发给用户时,Asp.net会处理大量资源。由于您不希望用户等待,因此您将遇到这种情况,您认为可以安全使用的ASP.NET对象确实已经处理掉了。
您最好的选择是创建一个外部服务(在IIS中运行的wcf服务,或者暴露了wcf接口的Windows服务).net页面可以异步调用该服务,并在该请求完成之前运行该请求。不用担心线程等。它运行在它自己的进程中,当它完成时就完成了。由于您不关心告诉用户已完成,因此您不必担心它会进行通信。这样,如果你需要让其他一些页面使用相同的服务接口,就可以调用它。
关于WCF入门的页面:
http://bloggingabout.net/blogs/dennis/archive/2007/04/20/wcf-simple-example.aspx
http://msdn.microsoft.com/en-us/library/bb332338.aspx
http://www.c-sharpcorner.com/Articles/ArticleListing.aspx?SectionID=1&SubSectionID=192
答案 1 :(得分:1)
这是另一个建议...... 如果您正在使用数据库,请创建一个任务(即创建一个表示要完成的任务的表)与需要发送的消息相关并使用Quartz.NET或类似的(您也可以创建一个Windows服务) )查找不完整的任务并执行它们(如果成功执行则将它们标记为已完成)。
答案 2 :(得分:0)
所以我的建议是使用ThreadPool。它允许你排队所有内容而不是分别运行它们,使它使用更少的资源,但当然,需要更长的时间来处理所有内容,但就像你说的那样,时间不是问题。
答案 3 :(得分:0)
您可以简单地使用BackgroundWorker类。
链接的MSDN页面有一个很好的例子,包括进度报告和取消操作的可能性。
修改强>
进度报告和取消可能不适合Web应用程序,但BackgroundWorker会为您创建一个线程来处理所有脏东西。
<强> EDIT2:强>
如果您想并行发送多封邮件,可以查看Task Parallel Library。
答案 4 :(得分:0)
您可以使用“任务”来生成工作线程以处理电子邮件。
如果这对CPU造成太大影响,您可以创建一个新的调度程序来减少并发性:http://msdn.microsoft.com/en-us/library/ee789351.aspx
static void StartMailTasks(string[] addresses)
{
List<Task> tasks = new List<Task>();
foreach (var address in addresses)
{
tasks.Add(Task.Factory.StartNew(Email, address));
}
Task.Factory.ContinueWhenAll(tasks.ToArray(), AllDone, TaskContinuationOptions.OnlyOnRanToCompletion);
Task.Factory.ContinueWhenAny(tasks.ToArray(), ReportError, TaskContinuationOptions.OnlyOnFaulted);
}
static void AllDone(Task[] tasks)
{
// All is well
}
static void ReportError(Task errorTask)
{
// Log or report the error
}
static void Email(object state )
{
// send the e-mail
// Can throw error, if needed
}