You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#基于SMTP如何实现每日指定时间自动发送带附件邮件

.NET平台无依赖实现工作日15点自动发邮件方案

不要直接写DateTime.Now == 下午3点的判断——这种精确到毫秒的相等判断,受轮询间隔、系统时间调度偏差影响,90%概率会错过触发点,而且写死循环轮询时间会平白占用CPU资源,用内置的异步延时逻辑就能零额外依赖实现需求。

核心定时逻辑

先写方法计算距离下一个触发时间的间隔,自动跳过非工作日、自动处理过点顺延的情况,不用手写周一到周五的重复判断:

DateTime GetNextTriggerTime()
{
    DateTime now = DateTime.Now;
    DateTime target = now.Date.AddHours(15); // 当日15点整

    // 当日15点已过,顺延到下一天
    if (now > target) target = target.AddDays(1);

    // 自动跳过周末,只保留工作日触发
    while (target.DayOfWeek is DayOfWeek.Saturday or DayOfWeek.Sunday)
    {
        target = target.AddDays(1);
    }
    return target;
}

然后写常驻的调度逻辑,用Task.Delay做非阻塞等待,等待期间几乎不消耗系统资源,比Thread.Sleep或者空循环轮询效率高很多:

async Task ScheduleRunner()
{
    while (true)
    {
        DateTime nextSend = GetNextTriggerTime();
        TimeSpan waitSpan = nextSend - DateTime.Now;
        
        // 等待到触发点
        await Task.Delay(waitSpan);
        // 执行发邮件逻辑
        await SendWorkEmail();
        // 发完等60秒,避免同一时间点重复触发
        await Task.Delay(TimeSpan.FromMinutes(1));
    }
}

邮件发送逻辑优化

你原有SMTP代码逻辑基本可用,调整下资源释放、附件匹配的逻辑,不用复制5段星期判断,用字典映射星期和对应附件路径即可:

async Task SendWorkEmail()
{
    try
    {
        // 配置各工作日对应附件路径,改路径直接改这里就行
        var weekAttachmentMap = new Dictionary<DayOfWeek, string>
        {
            [DayOfWeek.Monday] = @"C:\local\周一报表.xlsx",
            [DayOfWeek.Tuesday] = @"C:\local\周二报表.xlsx",
            [DayOfWeek.Wednesday] = @"C:\local\周三报表.xlsx",
            [DayOfWeek.Thursday] = @"C:\local\周四报表.xlsx",
            [DayOfWeek.Friday] = @"C:\local\周五报表.xlsx"
        };

        using var client = new SmtpClient("你的SMTP服务地址", 端口)
        {
            EnableSsl = false,
            DeliveryMethod = SmtpDeliveryMethod.Network,
            UseDefaultCredentials = false,
            Credentials = new NetworkCredential("发件邮箱账号", "发件邮箱密码")
        };

        using var msg = new MailMessage
        {
            IsBodyHtml = true,
            From = new MailAddress("你的发件邮箱地址"),
            Subject = "定时发送的工作邮件",
            Body = "你的HTML格式邮件正文"
        };
        msg.To.Add("收件人邮箱地址");

        // 自动匹配当天附件添加
        if (weekAttachmentMap.TryGetValue(DateTime.Now.DayOfWeek, out var attachPath))
        {
            msg.Attachments.Add(new Attachment(attachPath));
        }

        await client.SendMailAsync(msg);
        Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 邮件发送成功");
    }
    catch (Exception ex)
    {
        Console.WriteLine($"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] 发送失败:{ex.Message}");
    }
}

启动方式

如果是控制台程序,直接在入口函数调用调度方法即可:

// 程序启动后直接进入调度等待
await ScheduleRunner();

注意事项

  • 不需要额外安装数据库、第三方定时任务组件,所有逻辑都是.NET内置API实现
  • 开发调试阶段可以保持VS开着运行,正式用的时候编译成Release版本的exe直接双击后台运行即可,不需要一直开VS
  • 不要用空循环+时间相等判断的写法,既耗性能又容易漏触发,提前算等待时长的方式时间精度可以到毫秒级,完全满足准点发送需求
  • 如果需要临时调整发送时间,只需要改AddHours(15)里的小时数值就行,其他逻辑不用动

内容的提问来源于stack exchange,提问作者user12422846

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 20:03:24