Back to "E-maileiden taustan lähettäminen lisääminen"

This is a viewer only at the moment see the article on how this works.

To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk

This is a preview from the server running through my markdig pipeline

ASP.NET

E-maileiden taustan lähettäminen lisääminen

Wednesday, 07 August 2024

##Introduction

Edellä mainitussani esitin yksityiskohtaisesti, miten voin lähettää sähköpostia FluentEmailin ja SMTP-clientin avulla.. Yksi tähän liittyvä ongelma on kuitenkin sähköpostien lähettämisen viivästyminen.

Yksi tapa ratkaista tämä on lähettää sähköpostia taustalla. Tällä tavalla käyttäjä voi jatkaa soveltamista ilman, että hänen on odotettava sähköpostin lähettämistä. Tämä on yleinen malli web-sovellusissa ja se voidaan saavuttaa käyttämällä taustatehtävää

ASP.NET Coren taustavaihtoehdot

ASP:ssa on kaksi pääasiallista vaihtoehtoa ( Hangfiren kaltaisten kehittyneempien vaihtoehtojen lisäksi / Quartz

  • IHostedService - tämä vaihtoehto antaa perustavanlaatuisen elinkaaren hallintaa taustatehtävillenne
  • IHostedLifetime - tämä vaihtoehto antaa teille enemmän valvontaa taustatehtävienne elinkaaren suhteen. voitte myös käynnistää ja pysäyttää palvelun, ja se toimii taustalla, mutta teillä on enemmän hallintoa aloittaessa , pysäyttämälläM SK3 aloittaessaan M SK4 pysäyttäessään jne.

Tässä esimerkkissä I' käyttää yksinkertaista IHostedService-palvelua sähköpostien lähettämiseen taustalla

Lähdekoodi

Kokonaislähde tästä on jäljempänä.

Background Email Service
using System.Threading.Tasks.Dataflow;
using Mostlylucid.Email.Models;

namespace Mostlylucid.Email
{
    public class EmailSenderHostedService(EmailService emailService, ILogger<EmailSenderHostedService> logger)
        : IHostedService, IDisposable
    {
        private readonly BufferBlock<BaseEmailModel> _mailMessages = new();
        private Task _sendTask = Task.CompletedTask;
        private CancellationTokenSource cancellationTokenSource = new();

        public async Task SendEmailAsync(BaseEmailModel message)
        {
            await _mailMessages.SendAsync(message);
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            logger.LogInformation("Starting background e-mail delivery");
            // Start the background task
            _sendTask = DeliverAsync(cancellationTokenSource.Token);
            return Task.CompletedTask;
        }

        public async Task StopAsync(CancellationToken cancellationToken)
        {
            logger.LogInformation("Stopping background e-mail delivery");

            // Cancel the token to signal the background task to stop
            await cancellationTokenSource.CancelAsync();

            // Wait until the background task completes or the cancellation token triggers
            await Task.WhenAny(_sendTask, Task.Delay(Timeout.Infinite, cancellationToken));
        }

        private async Task DeliverAsync(CancellationToken token)
        {
            logger.LogInformation("E-mail background delivery started");

            while (!token.IsCancellationRequested)
            {
                BaseEmailModel? message = null;
                try
                {if(_mailMessages.Count == 0) continue;
                    message = await _mailMessages.ReceiveAsync(token);
                    switch (message)
                    {
                        case ContactEmailModel contactEmailModel:
                            await emailService.SendContactEmail(contactEmailModel);
                            break;
                        case CommentEmailModel commentEmailModel:
                            await emailService.SendCommentEmail(commentEmailModel);
                            break;
                    }
                    logger.LogInformation("Email from {SenderEmail} sent", message.SenderEmail);
                }
                catch (OperationCanceledException)
                {
                    break;
                }
                catch (Exception exc)
                {
                    logger.LogError(exc, "Couldn't send an e-mail from {SenderEmail}", message?.SenderEmail);
                    await Task.Delay(1000, token); // Delay and respect the cancellation token
                    if (message != null)
                    {
                        await _mailMessages.SendAsync(message, token);
                    }
                }
            }

            logger.LogInformation("E-mail background delivery stopped");
        }

        public void Dispose()
        {
            cancellationTokenSource.Cancel();
            cancellationTokenSource.Dispose();
        }
    }
}
Tässä voitte nähdä, että käsittelemme palvelun aloittamista ja uuden BufferBlockin käyttöönottoa sähköpostien säilyttämiseksi.
public class EmailSenderHostedService(EmailService emailService, ILogger<EmailSenderHostedService> logger)
        : IHostedService, IDisposable
    {
        private readonly BufferBlock<BaseEmailModel> _mailMessages = new();
        private Task _sendTask = Task.CompletedTask;
        private CancellationTokenSource cancellationTokenSource = new();

Olemme myös perustaneet uuden tehtävän toimittaaksemme sähköpostit taustalla. ja CancellationTokenSource, jonka avulla tehtävä voidaan peruuttaa hienovaraisesti, jos haluamme pysäyttää palvelun.

Sen jälkeen aloitamme HostedServicen StartAsync-järjestelmällä ja tarjoamme muiden palvelujen pääsyn, jotta ne voivat lähettää sähköpostin.

 public async Task SendEmailAsync(BaseEmailModel message)
        {
            await _mailMessages.SendAsync(message);
        }

        public Task StartAsync(CancellationToken cancellationToken)
        {
            logger.LogInformation("Starting background e-mail delivery");
            // Start the background task
            _sendTask = DeliverAsync(cancellationTokenSource.Token);
            return Task.CompletedTask;
        }

Meidän on nyt varmistettava palvelujen rekisteröiminen DI:n konttiin ja alettava HostedService.

       services.AddSingleton<EmailSenderHostedService>();
        services.AddHostedService(provider => provider.GetRequiredService<EmailSenderHostedService>());

Nyt voimme lähettää sähköpostia taustalla käyttämällä SendEmailAsync -menetelmää EmailSenderHostedService. e.gM SK1 yhteyslomakkeen osalta teemme tämän

            var contactModel = new ContactEmailModel()
            {
                SenderEmail = user.email,
                SenderName =user.name,
                Comment = commentHtml,
            };
            await sender.SendEmailAsync(contactModel);

Edellä olevaan koodiin lisätään tämä viesti BufferBlock<BaseEmailModel> _mailMessages ja taustatehtävä ottavat sen ja lähettävät sähköpostin.

   private async Task DeliverAsync(CancellationToken token)
        {
          ...

            while (!token.IsCancellationRequested)
            {
                BaseEmailModel? message = null;
                try
                {if(_mailMessages.Count == 0) continue;
                    message = await _mailMessages.ReceiveAsync(token);
                    switch (message)
                    {
                        case ContactEmailModel contactEmailModel:
                            await emailService.SendContactEmail(contactEmailModel);
                            break;
                        case CommentEmailModel commentEmailModel:
                            await emailService.SendCommentEmail(commentEmailModel);
                            break;
                    }
                    logger.LogInformation("Email from {SenderEmail} sent", message.SenderEmail);
           ...
            }

            logger.LogInformation("E-mail background delivery stopped");
        }

Tämä käy niin kauan kuin lopetamme palvelun ja jatkamme BufferBlockin seurantaa uusien sähköpostien lähettämiseksi.

logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.