如何在C#的ASP.NET Core项目中设置邮件发送延迟?
如何在ASP.NET Core Razor页面中设置邮件发送延迟?
当然可以设置邮件发送延迟,下面提供两种可行方案,根据你的场景选择:
方案一:简单延迟(不推荐生产环境)
如果只是测试需求,或者对用户等待时间不敏感,可以直接在发送邮件前添加延迟。但这种方式会阻塞当前请求线程,导致用户需要等待延迟结束才能收到响应,体验较差。
修改你的OnPostSendEmail方法:
public async Task OnPostSendEmail() { // 设置延迟时间,示例为10秒 await Task.Delay(TimeSpan.FromSeconds(10)); using (var smtp = new System.Net.Mail.SmtpClient("10.48.1.190")) { var emailMessage = new MailMessage(); emailMessage.From = new MailAddress(email.From); emailMessage.To.Add("enter email here"); emailMessage.Subject = email.Subject; emailMessage.Body = email.Body; await smtp.SendMailAsync(emailMessage); } }
方案二:后台任务延迟发送(推荐生产环境)
生产环境下,更合理的做法是将邮件发送任务放到后台执行,避免阻塞请求。可以通过ASP.NET Core的**托管服务(Hosted Service)**结合延迟队列实现:
步骤1:创建邮件任务模型
定义存储邮件信息和延迟时间的模型:
public class DelayedEmailTask { public EmailMessage Email { get; set; } public TimeSpan Delay { get; set; } }
步骤2:创建后台邮件队列服务
public class EmailTaskQueue { private readonly ConcurrentQueue<DelayedEmailTask> _queue = new(); private readonly SemaphoreSlim _signal = new(0); public void EnqueueTask(DelayedEmailTask task) { if (task == null) throw new ArgumentNullException(nameof(task)); _queue.Enqueue(task); _signal.Release(); } public async Task<DelayedEmailTask> DequeueAsync(CancellationToken cancellationToken) { await _signal.WaitAsync(cancellationToken); _queue.TryDequeue(out var task); return task; } }
步骤3:实现托管服务处理延迟任务
public class EmailBackgroundService : BackgroundService { private readonly EmailTaskQueue _taskQueue; private readonly IServiceProvider _serviceProvider; public EmailBackgroundService(EmailTaskQueue taskQueue, IServiceProvider serviceProvider) { _taskQueue = taskQueue; _serviceProvider = serviceProvider; } protected override async Task ExecuteAsync(CancellationToken stoppingToken) { while (!stoppingToken.IsCancellationRequested) { var task = await _taskQueue.DequeueAsync(stoppingToken); // 等待指定延迟时间 await Task.Delay(task.Delay, stoppingToken); // 创建作用域获取服务 using var scope = _serviceProvider.CreateScope(); var smtpClient = new System.Net.Mail.SmtpClient("10.48.1.190"); try { var emailMessage = new MailMessage(); emailMessage.From = new MailAddress(task.Email.From); emailMessage.To.Add("enter email here"); emailMessage.Subject = task.Email.Subject; emailMessage.Body = task.Email.Body; await smtpClient.SendMailAsync(emailMessage); } catch (Exception ex) { // 此处可添加日志记录,处理发送失败场景 } finally { smtpClient.Dispose(); } } } }
步骤4:注册服务到DI容器
在Program.cs中添加服务注册:
builder.Services.AddSingleton<EmailTaskQueue>(); builder.Services.AddHostedService<EmailBackgroundService>();
步骤5:修改Razor页面的Post方法
将邮件任务加入队列,指定延迟时间:
public class EmailRequestModel : PageModel { private readonly filedbContext _context; private readonly ApplicationDbContext _dbcontext; private readonly EmailTaskQueue _emailTaskQueue; public EmailRequestModel(filedbContext db, ApplicationDbContext dbcontext, EmailTaskQueue emailTaskQueue) { _dbcontext = dbcontext; _context = db; _emailTaskQueue = emailTaskQueue; } [BindProperty] public EmailMessage email { get; set; } public void OnGet() {} public async Task OnPostSendEmail() { // 设置延迟时间,示例为1分钟 var delayedTask = new DelayedEmailTask { Email = email, Delay = TimeSpan.FromMinutes(1) }; _emailTaskQueue.EnqueueTask(delayedTask); // 立即返回响应给用户,无需等待邮件发送 TempData["Message"] = "请求已提交,我们会稍后发送邮件!"; } }
这种方式下,用户提交表单后会立即收到响应,邮件会在后台延迟指定时间后发送,不会阻塞请求线程,更适合生产环境使用。
内容的提问来源于stack exchange,提问作者Megan Paterson
相关产品推荐
相关产品推荐

