.NET实现定时发送邮件代码(两种方式)

下面是“.NET实现定时发送邮件代码”攻略的详细讲解。

一、前言

邮件是现代人与人之间联系的重要方式之一,而定时发送邮件则可以让我们更加优雅的处理邮件,不用担心自己在某些时间段错过了发送重要邮件的时机。本文将演示两种.NET中定时发送邮件代码的实现方式,供参考。

二、第一种方式:使用System.Threading.Timer类

2.1 实现原理

使用System.Threading.Timer类,在指定的时间间隔内执行指定的代码,我们可以在定时器的回调函数中调用.Net自带的SMTP类库实现发送邮件的操作。

2.2 操作步骤

具体来说,下面是这种方式的操作步骤:

  1. 首先,我们需要创建一个回调函数,该函数接收一个object类型的参数用于定时回调时传入数据,返回void(不需要有返回值),在回调函数中我们可以执行发送邮件的代码。

举个例子,下面是一个简单的回调函数,在定时时间到达的时候输出一段文本:

private static void SendEmail(object state)
{
    Console.WriteLine("定时任务 - 发送邮件");
}
  1. 接下来,我们需要设置定时器,即在程序启动时启动一个定时器,使之在指定的时间间隔后回调我们的回调函数,并执行发送邮件的操作。

我们可以在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执行一次回调函数。

  1. 最后,在我们的回调函数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 操作步骤

具体来说,下面是这种方式的操作步骤:

  1. 首先,我们需要引入Quartz.NET框架,可以通过NuGet包管理器进行安装。

  2. 接下来,我们创建一个继承自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方法,在其中编写发送邮件的逻辑。

  1. 然后,在我们的程序启动函数中,我们需要通过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技术站

(0)
上一篇 2023年5月31日
下一篇 2023年5月31日

相关文章

  • SuperSocket封装成C#类库的步骤

    将SuperSocket封装成C#类库的步骤如下: 第一步,首先需要创建一个新的C#类库项目。打开Visual Studio,选择“新建项目”,选择“类库”类型并命名项目。 第二步,安装SuperSocket的NuGet包。在“解决方案资源管理器”中,右键点击“引用”文件夹,选择“管理NuGet程序包”。在搜索栏中输入“SuperSocket”,安装最新版本…

    C# 2023年6月1日
    00
  • C#实现简单的窗口抖动

    C#实现简单的窗口抖动攻略 本文将介绍如何用C#语言实现简单的窗口抖动效果。用于提示用户操作错误等情况,增加用户的交互体验。 原理说明 窗口抖动的原理是通过快速切换窗口的位置来实现,具体做法是: 获取当前窗口的位置信息 在原位置上左右、上下抖动一定的距离 还原窗口至原位置 循环完成上述过程 实现过程 1. 获取当前窗口位置信息 在Form类的成员方法中,可以…

    C# 2023年6月6日
    00
  • Asp.Net Core 使用Monaco Editor 实现代码编辑器功能

    下面就对”Asp.Net Core 使用Monaco Editor 实现代码编辑器功能”进行详细讲解。 1. 什么是Monaco Editor Monaco Editor是一款基于Web的代码编辑器,由微软开发并开源。它在Visual Studio Code中使用,支持多种语言、语法高亮、自动完成、智能提示、代码跳转等功能。 2. Asp.Net Core …

    C# 2023年5月31日
    00
  • Unity ScrollView实现自动吸附效果

    我将详细讲解一下“Unity ScrollView实现自动吸附效果”的完整攻略。 一、准备工作 创建一个空的Unity项目 创建一个Canvas,将Canvas的Render Mode设置为Screen Space – Overlay 在Canvas下面创建一个ScrollView,将ScrollView的Content的Layout Group设置为Ver…

    C# 2023年6月3日
    00
  • C#判断字符串中是否包含指定字符串及contains与indexof方法效率问题

    C#中判断一个字符串是否包含子字符串是一个常用的任务。本文将讲解如何使用C#的contains和indexof方法来实现这个任务,并探讨它们的效率问题。 contains方法 contains方法是String类中的一种方法,用于判断一个字符串是否包含指定的子字符串。代码示例如下: string str1 = "hello world";…

    C# 2023年6月8日
    00
  • 在C#中使用SQLite数据库

    轻量级桌面程序数据库不太适合用SQLServer、MySQL之类的重量级数据库,嵌入式数据库更好。在对比Access、SQLite、Firebird数据库后发现SQLite较另外两个有较多优点。 环境:.NET Framework 3.5、windows11 64位、Visual Studio 2010. C#使用SQLite需要从SQLite官网下载DLL…

    C# 2023年4月24日
    00
  • 浅析C# 状态机Stateless

    浅析C#状态机Stateless 什么是状态机? 状态机(State Machine)是一种强大的工具,用来描述系统在不同状态下如何进行状态转移以及如何对状态进行处理。在软件主题下,状态机通常被用于设计一些流程型的业务场景,例如订单状态,审批流程,游戏角色状态等。 介绍Stateless库 Stateless是一个由C#语言编写的状态机库,可以帮助我们快速高…

    C# 2023年5月15日
    00
  • 在Unity中实现动画的正反播放代码

    下面是在Unity中实现动画的正反播放代码的完整攻略。 1. 实现动画正播放 要在Unity中实现动画的正播放,首先需要将动画文件添加到项目中。可以通过在“Project”窗口中右键单击,选择“Import New Asset”选项,然后选择要添加的动画文件。 接下来,在场景中选择要添加动画的对象,然后拖动动画文件到对象的“Animator”组件上。此时,可…

    C# 2023年6月3日
    00
合作推广
合作推广
分享本页
返回顶部