带定时器控制的自动电子邮件发送
本文关键字:电子邮件 定时器 控制 | 更新日期: 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()
方法将包含实际发送电子邮件的逻辑。将内容添加到队列的代码将是用于从数据库中提取信息的任何逻辑,当然,您将提到的限制添加到数据库中的基准日期,以确定实际过期时间的时间。
以上都假设你的一般状态是相对不变的。它可以轻松处理添加新事件,这些事件将比已排队的任何其他事件晚发生。对于更复杂的任何操作,例如处理用户的基本时间在其事件过期之前更新的方案,或者添加基准时间早于最近已排队时间的新用户,需要在基础队列和处理中进行一些更改。
确切的细节在很大程度上取决于您实际需要做什么。 希望以上内容能为您提供足够好的推动力,朝着正确的方向前进,您可以对其进行改进以满足您的特定需求,但是当然,如果您在适应时遇到困难,请随时提出另一个问题。