NOTE: Apart from
(and even then it's questionable, I'm Scottish). These are machine translated in languages I don't read. If they're terrible please contact me.
You can see how this translation was done in this article.
Wednesday, 07 August 2024
//Less than a minute
"Käynnistäminen"
Edellisessä viestissäni kerroin yksityiskohtaisesti, kuinka lähettää sähköposteja FluentEmailin ja SMTP-asiakkaan kautta. Yksi ongelma tässä on kuitenkin sähköpostien lähettämisen viivästyminen. SMTP-palvelimet ovat yleensä hitaita ja sähköpostien lähettäminen voi kestää jonkin aikaa. Tämä voi olla ärsyttävää käyttäjille, ja se voi tuntua sovelluksessasi logjamilta.
Yksi tapa kiertää tämä on lähettää taustalle sähköposteja. Näin käyttäjä voi jatkaa sovelluksen käyttöä tarvitsematta odottaa sähköpostin lähettämistä. Tämä on yleinen malli verkkosovelluksissa, ja se voidaan saavuttaa taustatyön avulla.
[TÄYTÄNTÖÖNPANO
ASP.NET Coressa on kaksi päävaihtoehtoa (kuten Hangfire / Quartz)
Tässä esimerkissä käytän yksinkertaista IHostedServiceä sähköpostien lähettämiseen taustalla.
Täydellinen lähde tälle on alla.
namespace Mostlylucid.Email
{
public class EmailSenderHostedService(EmailService emailService, ILogger
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>
Tässä näet, että hoidamme palvelun alun ja perustamme uuden BufferBlockin pitämään sähköpostit.
```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();
Perustimme myös uuden tehtävän, jolla toimitamme sähköpostit taustalla. ja PeruutusTokenLähde peruuttaa tehtävän sulavasti, kun haluamme lopettaa palvelun.
Aloitamme sen jälkeen StartAsyncillä HostedService -palvelun ja lähetämme sähköpostia muille palveluille.
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;
}
Setup-kurssilla meidän täytyy nyt rekisteröidä palvelu DI-konttiin ja aloittaa HostedService
services.AddSingleton<EmailSenderHostedService>();
services.AddHostedService(provider => provider.GetRequiredService<EmailSenderHostedService>());
Nyt voimme lähettää sähköpostia taustalla soittamalla SenderEmailAsync -menetelmään sähköpostitseSenderSenderHostedService -palvelussa. Esimerkiksi yhteydenottolomaketta varten teemme näin.
var contactModel = new ContactEmailModel()
{
SenderEmail = user.email,
SenderName =user.name,
Comment = commentHtml,
};
await sender.SendEmailAsync(contactModel);
Yllä olevassa koodissa tämä lisää tämän viestin BufferBlock<BaseEmailModel>
_Postiviestit ja taustatehtävä poimivat 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ä sitten silmukka kunnes lopetamme palvelun ja jatkamme BufferBlockin seuraamista uusien sähköpostien lähettämiseksi.