带定时器控制的自动电子邮件发送

本文关键字:电子邮件 定时器 控制 | 更新日期: 2023-09-27 18:33:13

我需要创建一个自动电子邮件发件人系统C#,该系统需要从一个数据库中读取数据。该数据主要是日期时间和ID。对于每个日期,我需要计算插入的日期与系统的当前日期之间的差异。我已经写了几段代码来发送邮件:

private void button1_Click(object sender, EventArgs e)
{   
 var fromAddress = new MailAddress("xxx@gmail.com", "NAME1");
 var toAddress = new MailAddress("aaa@gmail.com", "To Name");
 const string fromPassword = "pass";
 const string subject = "TEST";
 const string body = "WARNING";
 var smtp = new SmtpClient
  {
   Host = "smtp.gmail.com",
   Port = 587,
   EnableSsl = true,
   DeliveryMethod = SmtpDeliveryMethod.Network,
   UseDefaultCredentials = false,
   Credentials = new NetworkCredential(fromAddress.Address, fromPassword)
  };
 using (var message = new MailMessage(fromAddress, toAddress)
 {
  Subject = subject,
  Body = body
  })
  {
  smtp.Send(message);
  }
 }

我需要用计时器和每次启动应用程序时来控制它,但前提是日期达到限制。

在表单加载中,我阅读了所有日期以及需要通过此电子邮件通知日期结束的人。我这样做:

string constring4 = Classe_Ligacao.cn;
string Query4 = "select DATE,IDPerson from Diligencia Where DATE IS NOT NULL";
SqlConnection cn4 = new SqlConnection(constring4);
SqlCommand cmd4 = new SqlCommand(Query4, cn4); 
try
{
 cn4.Open();
 using (SqlDataReader read4 = cmd4.ExecuteReader())
 {
  while (read4.Read())
  {
   string pr = (read4["DATE"].ToString());
   string ida = (read4["IDPerson"].ToString());
   string constring2 = Classe_Ligacao.cn;
   string query2 = "select name,Email  FROM Person WHERE IDPerson='" + ida + "'";
   SqlConnection cn2 = new SqlConnection(constring2); 
   SqlCommand cmd2 = new SqlCommand(query2, cn2);
   cn2.Open();
   using (SqlDataReader read2 = cmd2.ExecuteReader())
   {
     while (read2.Read())
     {
      string ab = (read2["Name"].ToString());
      string ema = (read2["Email"].ToString());
      MessageBox.Show(ab, ema);
     }
    }
   cn2.Close();
  }
 }
}
finally
{
cn4.Close();
}

我需要关联要发送的电子邮件、日期和距离日期结束的剩余天数。我该怎么做,将所有内容关联到计时器?

希望你能理解我的问题。

带定时器控制的自动电子邮件发送

基本概念很容易实现:在一个循环中,从下一个操作的时间(即您下次需要发送电子邮件的时间(中减去当前时间,然后等待该时间长度。

例如:

static async Task ProcessSchedule(IEnumerable<DateTime> schedule)
{
    // Release caller
    await Task.Yield();
    // Process the queue
    foreach (DateTime eventTime in schedule)
    {
        TimeSpan nextEvent = eventTime - DateTime.UtcNow;
        Console.Write(
            "waiting {0:0.000} seconds...", Math.Max(0, nextEvent.TotalSeconds));
        if (nextEvent.Ticks > 0)
        {
            await Task.Delay(nextEvent);
        }
        Console.WriteLine(eventTime);
    }
}

当我这样称呼上面时:

// Setup
double[] futureSeconds = { 1, 2.5, 3.7, 5, 9, 12.2, 15 };
BlockingCollection<DateTime> queue = new BlockingCollection<DateTime>();
Task task = ProcessSchedule(queue.GetConsumingEnumerable());
// This would be equivalent to whatever process you have generating
// the DateTime-based events (e.g. reading from a database)
DateTime startTime = DateTime.UtcNow;
foreach (DateTime eventTime in futureSeconds.Select(s => startTime + TimeSpan.FromSeconds(s)))
{
    queue.Add(eventTime);
}
// Don't call this until you want processing to stop
queue.CompleteAdding();
task.Wait();

我得到以下输出:

等待 1.000 秒...2014/12/5 19
:35:43 等待 1.469 秒...2014/12/5 19
:35:45 等待 1.184 秒...2014/12/5 19
:35:46 等待 1.297 秒...2014/12/5 19
:35:47 等待 3.984 秒...2014/12/5 19
:35:51 等待 3.184 秒...2014/12/5 19
:35:54 等待 2.797 秒...2014/12/5 19:35:57

请注意,每个延迟都不是您期望从初始化秒数中获得的全部延迟。 即,虽然第二个事件发生在开始时间后 2.5 秒,但只有 1.469 秒的延迟。这是因为该技术会自动考虑处理上一个事件所花费的时间,

然后再等待。

当然,在上面,您可以将队列类型替换为包含详细信息的任何对象,例如用户下一封电子邮件通知的DateTime,当然还有他们通过电子邮件发送的详细信息。ProcessSchedule()方法将包含实际发送电子邮件的逻辑。将内容添加到队列的代码将是用于从数据库中提取信息的任何逻辑,当然,您将提到的限制添加到数据库中的基准日期,以确定实际过期时间的时间。

以上都假设你的一般状态是相对不变的。它可以轻松处理添加新事件,这些事件将比已排队的任何其他事件晚发生。对于更复杂的任何操作,例如处理用户的基本时间在其事件过期之前更新的方案,或者添加基准时间早于最近已排队时间的新用户,需要在基础队列和处理中进行一些更改。

确切的细节在很大程度上取决于您实际需要做什么。 希望以上内容能为您提供足够好的推动力,朝着正确的方向前进,您可以对其进行改进以满足您的特定需求,但是当然,如果您在适应时遇到困难,请随时提出另一个问题。