Προσθήκη αποστολής βάσης για μηνύματα ηλεκτρονικού ταχυδρομείου (ελληνικά (Greek))

Προσθήκη αποστολής βάσης για μηνύματα ηλεκτρονικού ταχυδρομείου

Wednesday, 07 August 2024

//

4 minute read

##Εισαγωγή

Στην προηγούμενη ανάρτησή μου έγραψα λεπτομερώς πώς να στείλετε μηνύματα ηλεκτρονικού ταχυδρομείου χρησιμοποιώντας το FluentEmail και τον SMTP Client. Ωστόσο, ένα πρόβλημα με αυτό είναι η καθυστέρηση στην αποστολή μηνυμάτων ηλεκτρονικού σταχυδρομίου. οι διακομιστές SMTP τείνουν να είναι αργές και μπορεί να πάρει λίγο χρόνο για να στέλνετε μηνύσεις emailM SK2 Αυτό μπορεί να είναι ενοχλητικό για τους χρήστες και να αισθάνεται σαν ένα logjam στην εφαρμογή σαςMK3

Ένας τρόπος για να φτάσετε γύρω από αυτό είναι να στείλετε μηνύματα ηλεκτρονικού ταχυδρομείου στο υπόβαθρο. Με αυτόν τον τρόπο ο χρήστης μπορεί να συνεχίσει να χρησιμοποιεί την εφαρμογή χωρίς να χρειάζεται να περιμένει το e-mail για να στέλνειΜSK1 Αυτό είναι ένα κοινό πρότυπο στις διαδικτυακές εφαρμογές και μπορεί να επιτευχθεί χρησιμοποιώντας μια εργασία υπόβασης.

Επιλογές βάσης στο ASP.NET Core

Στο ASP.NET Core έχετε δύο κύριες επιλογές (περισσότερες προηγμένες επιλογές όπως Hangfire ΜSK2QuartzM SK3

  • IHostedService - ίσως αυτή η επιλογή σας δίνει τη βασική διαχείριση του κύκλου ζωής για τα καθήκοντά σας υπόβαθρου. Μπορείτε να ξεκινήσετε και να σταματήσετε την υπηρεσία και θα τρέξει στο υπόβαθοςM SK2
  • IHostedLifetime - ίσως αυτή η επιλογή σας δίνει περισσότερο έλεγχο κατά τη διάρκεια του κύκλου ζωής των εργασιών υπόβαθρου σαςΜSK1 Μπορείτε επίσης να ξεκινήσετε και να σταματήσετε την υπηρεσία και θα τρέξει στο υπόβαθος αλλά έχετε περισσότερη δύναμη ελέγχου αρχίζοντας, σταματώντας

Σε αυτό το παράδειγμα, θα χρησιμοποιήσω ένα απλό IHostedService για να στείλω μηνύματα ηλεκτρονικού ταχυδρομείου στο υπόβαθρο.

Κωδικός πηγής

Η πλήρης πηγή για αυτό είναι κάτω.

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();
        }
    }
}
Εδώ μπορείτε να δείτε ότι χειρίζουμε την έναρξη της υπηρεσίας και δημιουργούμε ένα νέο BufferBlock για να κρατήσουμε τα 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();

Επίσης, δημιουργήσαμε μια νέα εργασία για να παραδώσουμε τα μηνύματα ηλεκτρονικού ταχυδρομείου στο υπόβαθρο. και μια ακύρωσηTokenSource για να ακυρώσει το έργο ευγενικά όταν θέλουμε να σταματήσουμε την υπηρεσία.

Στη συνέχεια ξεκινάμε την HostedService με StartAsync και παρέχουμε το σημείο εισόδου για άλλες υπηρεσίες για να στείλουμε ένα email.

 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;
        }

Στην κατηγορία Εισαγωγής μας πρέπει τώρα να εγγραφούμε στην υπηρεσία με το δοχείο DI και να ξεκινήσουμε την HostedService

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

Τώρα μπορούμε να στείλουμε μηνύματα ηλεκτρονικού ταχυδρομείου στο υπόβαθρο κάνοντας τη μέθοδο SendEmailAsync στο EmailSenderHostedService. e.ΜSK1 για τη φόρμα επαφής το κάνουμε αυτό ΜSK2

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

Στο παραπάνω κώδικα προσθέτει αυτό το μήνυμα στο δικό μας BufferBlock<BaseEmailModel> _mailMessages και η εργασία υπόβαθρου θα την πάρει και να στείλει το email.

   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");
        }

Αυτό θα διαρκέσει μέχρι να σταματήσουμε την υπηρεσία και συνεχίσουμε να παρακολουθούμε το BufferBlock για νέα μηνύματα ηλεκτρονικού ταχυδρομείου για να στείλουμε.

Finding related posts...
logo

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