# ईमेल के लिए पृष्ठभूमि प्रेषण जोड़ें

<!--category-- ASP.NET -->
<datetime class="hidden">2024-08-07T08:15</datetime>

आरंभ

अपने पिछले पोस्ट में मैंनेfluentEmail और एसएमटीपी क्लाइंट का उपयोग करते हुए ईमेल भेजने के बारे में विनिर्दिष्ट किया है।

इसे दूर करने का एक तरीका है पृष्ठभूमि में ईमेल भेजना।

[TOC]

## ASP.NET कोर में पृष्ठभूमि विकल्प

ASP में आप दो मुख्य विकल्प हैं ( Hangfire जैसे अधिक उन्नत विकल्पों के अलावा

- IHostedService - यह विकल्प आपको आपके पृष्ठभूमि कार्यों के लिए मूल जीवन चक्र प्रबंधन देता है
- IHostedLifetime - यह विकल्प आपको पृष्ठभूमि कार्यों के जीवन चक्र पर अधिक नियंत्रण प्रदान करता है. आप भी सेवा शुरू और बंद कर सकते हैं और यह पृष्ठभूमि में चला जाएगा लेकिन आपके पास अधिक नियंत्रण है आरंभ करने से आरंभिक

इस उदाहरण में मैं एक सरल IHostedService का उपयोग करता हूँ पृष्ठभूमि में ईमेल भेजने के लिए

## स्रोत कोड

इसके लिए पूरा स्रोत नीचे है

<details>
<summary>Background Email Service</summary>

```csharp
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();
        }
    }
}
```

</details>
यहाँ आप देख सकते हैं हम सेवा के आरंभ को संभालने और नए बफरब्लॉक सेटअप करने के लिए ईमेलों को रखने के लिए

```csharp
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();
```

हमने पृष्ठभूमि में ईमेल भेजने के लिए एक नया कार्य भी स्थापित किया
और CancellationTokenSource जब हम सेवा को रोकना चाहते हैं तो कार्य को शालीन रूप से रद्द करने के लिए

तब हम StartAsync के साथ होस्टेड सर्विस आरंभ करते हैं और एक ईमेल भेजने के लिए अन्य सेवाओं के लिए प्रविष्टि बिन्दु उपलब्ध कराते हैं

```csharp
 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 कंटेनर के साथ सेवा पंजीकृत करने और होस्टेड सर्विस शुरू करने की जरूरत है

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

अब हम EmailSenderHostedService पर SendEmailAsync विधि को कॉल करके पृष्ठभूमि में ईमेल भेज सकते हैं
संपर्क फॉर्म के लिए हम यह करते हैं

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

उपरोक्त कोड में यह संदेश हमारे `BufferBlock<BaseEmailModel>` _mailMessages और पृष्ठभूमि कार्य इसे उठा लेगा और ईमेल भेजेगा

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

यह तब लूप होगा जब तक हम सेवा रोकें और नए ईमेल भेजने के लिए बफरब्लॉक पर निगरानी जारी रखें