下面是“.NET实现定时发送邮件代码”攻略的详细讲解。
一、前言
邮件是现代人与人之间联系的重要方式之一,而定时发送邮件则可以让我们更加优雅的处理邮件,不用担心自己在某些时间段错过了发送重要邮件的时机。本文将演示两种.NET中定时发送邮件代码的实现方式,供参考。
二、第一种方式:使用System.Threading.Timer类
2.1 实现原理
使用System.Threading.Timer类,在指定的时间间隔内执行指定的代码,我们可以在定时器的回调函数中调用.Net自带的SMTP类库实现发送邮件的操作。
2.2 操作步骤
具体来说,下面是这种方式的操作步骤:
- 首先,我们需要创建一个回调函数,该函数接收一个object类型的参数用于定时回调时传入数据,返回void(不需要有返回值),在回调函数中我们可以执行发送邮件的代码。
举个例子,下面是一个简单的回调函数,在定时时间到达的时候输出一段文本:
private static void SendEmail(object state)
{
Console.WriteLine("定时任务 - 发送邮件");
}
- 接下来,我们需要设置定时器,即在程序启动时启动一个定时器,使之在指定的时间间隔后回调我们的回调函数,并执行发送邮件的操作。
我们可以在Console应用或者Web应用的启动函数中放置启动定时器的代码:
using System.Threading;
class Program
{
private static Timer timer;
static void Main(string[] args)
{
timer = new Timer(SendEmail, null, 0, 10000); // 设置定时器,在10s后启动一次,每10s执行一次
}
}
在上述代码中,我们创建了一个名为timer的静态变量来存储我们的定时器实例,然后在Main函数中初始化该实例,并指定定时器的回调函数为SendEmail,以及指定callback参数为null,因为我们的回调函数不需要传入额外的数据。
此外,在定时器实例的构造函数中,我们还指定了两个时间延迟参数,第一个参数表示初始化后多少秒之后启动定时器,这里我们设置为0,表示程序启动后即刻启动。第二个参数表示定时器多久后执行一次回调函数,以毫秒为单位,这里我们设置为10000,表示每10s执行一次回调函数。
- 最后,在我们的回调函数SendEmail中,我们可以调用.Net自带的SMTP类库实现发送邮件的操作。
private static void SendEmail(object state)
{
var msg = new MailMessage();
msg.From = new MailAddress("from@example.com", "From Example");
msg.To.Add(new MailAddress("to@example.com"));
msg.Subject = "Test Email";
msg.Body = "This is a test email.";
var client = new SmtpClient("smtp.example.com", 25);
client.EnableSsl = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("from@example.com", "password");
client.Send(msg);
Console.WriteLine("定时任务 - 发送邮件");
}
在上述代码中,我们创建了一个MailMessage实例,指定了发件人、收件人、主题和内容等信息。然后我们创建了一个SmtpClient实例,指定了SMTP服务器的地址和端口,以及SMTP认证的邮箱和密码等信息。最后调用client对象的Send方法发送邮件。
2.3 示例说明
下面是一个完整的示例代码,该代码演示了在网站启动时设置一个定时器,在每隔10s后执行SendEmail函数,该函数实现了发送一封测试邮件的操作:
using System;
using System.Net;
using System.Net.Mail;
using System.Threading;
namespace EmailSender
{
class Program
{
private static Timer timer;
static void Main(string[] args)
{
Console.WriteLine("Email Sender - Service Started...");
// 启动定时器
timer = new Timer(SendEmail, null, 0, 10000);
Console.ReadLine();
}
private static void SendEmail(object state)
{
var msg = new MailMessage();
msg.From = new MailAddress("from@example.com", "From Example");
msg.To.Add(new MailAddress("to@example.com"));
msg.Subject = "Test Email";
msg.Body = "This is a test email.";
var client = new SmtpClient("smtp.example.com", 25);
client.EnableSsl = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("from@example.com", "password");
client.Send(msg);
Console.WriteLine("定时任务 - 发送邮件");
}
}
}
需要注意的是,上述代码中的SMTP服务器地址、发件人邮箱、发件人密码、收件人邮箱等都需要根据自己的情况进行修改。
三、第二种方式:使用Quartz.NET框架
3.1 实现原理
Quartz.NET是一个成熟的开源任务调度框架,可以满足比System.Threading.Timer更多样化的定时任务需求,且支持多种类型的任务调度,比如Cron表达式等。
使用Quartz.NET框架,我们可以编写一个任务类并在其中实现发送邮件的逻辑,然后在Quartz.NET的配置文件中指定我们的任务类和其执行时间。
3.2 操作步骤
具体来说,下面是这种方式的操作步骤:
-
首先,我们需要引入Quartz.NET框架,可以通过NuGet包管理器进行安装。
-
接下来,我们创建一个继承自IJob接口的任务类,并实现Execute方法,在其中编写发送邮件的逻辑。需要注意,该方法应该是一个无返回值的异步方法(async void),这是为了让Quartz.NET框架正确地管理任务状态。
这里再举一个例子,发送邮件的逻辑与之前相同,但是我们需要将其封装到一个可复用的任务类中:
using System.Net;
using System.Net.Mail;
using Quartz;
namespace EmailSender
{
public class EmailJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
var msg = new MailMessage();
msg.From = new MailAddress("from@example.com", "From Example");
msg.To.Add(new MailAddress("to@example.com"));
msg.Subject = "Test Email";
msg.Body = "This is a test email.";
var client = new SmtpClient("smtp.example.com", 25);
client.EnableSsl = true;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("from@example.com", "password");
await client.SendMailAsync(msg);
}
}
}
在上述代码中,我们定义了一个名为EmailJob的任务类,并实现了IJob接口的Execute方法,在其中编写发送邮件的逻辑。
- 然后,在我们的程序启动函数中,我们需要通过Quartz.NET的配置文件(通常为App.config或Web.config)来指定我们的任务类和其执行时间。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="quartz"
type="Quartz.Impl.StdSchedulerFactory, Quartz" />
</configSections>
<quartz>
<add key="quartz.scheduler.instanceName" value="ExampleScheduler" />
<add key="quartz.threadPool.type" value="Quartz.Simpl.SimpleThreadPool, Quartz" />
<add key="quartz.threadPool.threadCount" value="3" />
<add key="quartz.threadPool.threadPriority" value="Normal" />
</quartz>
<appSettings>
<add key="WelcomeMessage" value="Hello, World!" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.7.2" />
<httpRuntime targetFramework="4.7.2" />
</system.web>
<system.serviceModel>
<services>
<service name="WcfService1.Service1">
<endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- To avoid disclosing metadata information, set the values below to false before deployment -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/>
<!-- To receive exception details in faults for debugging purposes, set the value below to true. Set to false before deployment to avoid disclosing exception information -->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="basicHttpBinding" scheme="http"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true"/>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="log4net" publicKeyToken="1b44e1d426115821" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.0.8.0" newVersion="2.0.8.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<scheduler>
<trigger type="simple" name="EmailTrigger" misfire-instruction="FireNow">
<job group="email" name="EmailJob" />
<repeat-count>-1</repeat-count>
<repeat-interval>10000</repeat-interval>
</trigger>
<job-detail group="email" name="EmailJob">
<job-type>EmailSender.EmailJob, EmailSender</job-type>
</job-detail>
</scheduler>
</configuration>
在上述XML文件中,我们指定了Quartz.NET框架的一些基本配置,以及我们的任务类。具体来说,我们通过trigger元素定义了定时器的触发器,即每隔10s运行一次,并指定了job元素代表的任务类,通过job-detail元素指定任务类的全限定名称。需要注意的是,任务类的程序集名称通常也需要指定。
其中,<trigger>
元素包含以下子元素:
type
:定时器类型,这里我们使用的是简单定时器类型。name
:该定时器的名称。misfire-instruction
:触发器的误差处理方式,这里我们使用的是快速恢复模式,即在调度周期内错过了第一次执行时间就立即执行后续所有执行时间。
<job>
元素表示的是任务,包含以下子元素:
group
:任务分组,一般用于区分不同的任务。name
:任务名称,全局唯一。<trigger>
元素(决定了何时执行该任务)。
最后,我们需要在程序部署时将App.config或Web.Config文件部署到服务器上或者将其配置写在程序中。
3.3 示例说明
下面是一个完整的示例代码,该代码中使用了Quartz.NET框架,以每10s发送一封邮件为例:
using System;
using Quazrtz;
using Quartz.Impl;
using Quartz;
using EmailSender;
namespace EmailSender
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Email Sender - Service Started...");
RunScheduler();
}
private static void RunScheduler()
{
ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
IScheduler scheduler = schedulerFactory.GetScheduler().Result;
scheduler.Start();
IJobDetail emailJob = JobBuilder.Create<EmailJob>().Build();
ITrigger emailTrigger = TriggerBuilder.Create()
.WithIdentity("EmailTrigger", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10) // 定时执行间隔
.RepeatForever())
.Build();
scheduler.ScheduleJob(emailJob, emailTrigger);
}
}
}
在上述代码中,我们在程序启动函数中调用RunScheduler函数,来启动Quartz.NET的Scheduler。然后我们通过JobBuilder类和IJobDetail接口创建一个EmailJob的实例,同时通过TriggerBuilder类和ITrigger接口创建一个EmailTrigger的实例,并在其中指定EmailJob的实例和其调度规则。
需要注意的是,在示例代码的最后,我们需要使用scheduler.ScheduleJob方法将任务和触发器绑定在一起并加入调度器中,以便计划后续执行。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.NET实现定时发送邮件代码(两种方式) - Python技术站