我有一个应用程序,其中一个操作触发了许多要发送的电子邮件。电子邮件的数量是可变的,每次操作可以从 10 到 1,000 封不等。
我不希望应用程序在发送电子邮件时挂起(从而使用户烦恼)并且希望在后台发送它们。
我过去没有使用过 Threads,所以我需要你的帮助。您会手动创建线程还是使用 ThreadPool 的好案例?我希望此任务的优先级较低并尽可能使用最少的资源,因为即使电子邮件迟到 1 小时我也不介意。
感谢您的帮助
马尔科
我有一个应用程序,其中一个操作触发了许多要发送的电子邮件。电子邮件的数量是可变的,每次操作可以从 10 到 1,000 封不等。
我不希望应用程序在发送电子邮件时挂起(从而使用户烦恼)并且希望在后台发送它们。
我过去没有使用过 Threads,所以我需要你的帮助。您会手动创建线程还是使用 ThreadPool 的好案例?我希望此任务的优先级较低并尽可能使用最少的资源,因为即使电子邮件迟到 1 小时我也不介意。
感谢您的帮助
马尔科
说实话,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
这里有另一个建议......如果你正在使用数据库,创建一个与需要发送的消息相关的任务(即创建一个代表要完成的任务的表)并使用Quartz.NET或类似的(你可以创建一个 Windows 服务)查找未完成的任务并执行它们(将它们标记为已完成,以防它们成功执行)。
您可以使用任务来生成工作线程来处理电子邮件。
如果这对 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
}
所以我的建议是使用ThreadPool。它将允许您将所有内容排队,而不是单独运行它们中的每一个,使其使用更少的资源,但当然,处理所有内容需要更长的时间,但就像您说的那样,时间不是问题。
您可以简单地使用BackgroundWorker类。
链接的 MSDN 页面有一个很好的示例,其中包含进度报告和取消操作的可能性。
编辑:
进度报告和取消可能不适合 Web 应用程序,但 BackgroundWorker 会通过为您创建线程来处理所有脏东西。
Edit2:
如果您想并行发送许多邮件,您可以查看Task Parallel Library。