Как да изпълним асинхронни IMAP операции върху имейли
Асинхронни операции с ImapClient
Работата със съобщения може да се извършва асинхронно, като се използва Aspose.Email ImapClient. Тази статия показва асинхронно извличане на съобщения от пощенска кутия. Тази статия също показва как да изброявате съобщения, като предоставяте критерии за търсене, използвайки MailQuery. Ще бъде показано отделно как да се прекъсне операция с имейл съобщения, стартирана от асинхронен модел, основан на задачи (TAP) метод.
Извличане на съобщения асинхронно
Следният кодов фрагмент показва как да се извличат съобщения асинхронно.
Списък със съобщения асинхронно с MailQuery
Този MailQuery класът може да се използва за задаване на критерии за търсене при извличане на определен списък от съобщения асинхронно, както е показано в следния пример с код.
Изпращане на съобщения асинхронно
Изпращането на имейли асинхронно е много удобно, тъй като процесът не блокира изпълнението на програмата или нишката. Вместо да чакате имейлът да бъде изпратен, преди да продължите с други задачи, програмата може да продължи да работи, докато имейлът се изпраща във фонов режим.
Следните функции ще ви помогнат да внедрите асинхронно изпращане във вашия проект:
-
IAsyncImapClient - Позволява на приложенията да достъпват и манипулират съобщения, като използват протокола Internet Message Access Protocol (IMAP).
-
ImapClient.CreateAsync - Създава нов екземпляр на класа Aspose.Email.Clients.Imap.ImapClient
Примерният код по-долу демонстрира как да изброявате съобщенията във фонов режим:
// Authenticate the client to obtain necessary permissions
static readonly string tenantId = "YOU_TENANT_ID";
static readonly string clientId = "YOU_CLIENT_ID";
static readonly string redirectUri = "http://localhost";
static readonly string username = "username";
static readonly string[] scopes = { "https://outlook.office.com/IMAP.AccessAsUser.All" };
// Use the ImapAsync method for asynchronous operations
static async Task Main(string[] args)
{
await ImapAsync();
Console.ReadLine();
}
// Establish the connection with the server
// Create an instance of the ImapClient asynchronously using the CreateAsync method
// Select the Inbox folder using SelectFolderAsync method to complete and fetch the list of email messages asynchronously using the ListMessagesAsync method.
static async Task ImapAsync()
{
var tokenProvider = new TokenProvider(clientId, tenantId, redirectUri, scopes);
var client = ImapClient.CreateAsync("outlook.office365.com", username, tokenProvider, 993).GetAwaiter().GetResult();
await client.SelectFolderAsync(ImapFolderInfo.InBox);
var messages = await client.ListMessagesAsync();
Console.WriteLine("Messages :" + messages.Count);
}
// Token provider implementation
public class TokenProvider : IAsyncTokenProvider
{
private readonly PublicClientApplicationOptions _pcaOptions;
private readonly string[] _scopes;
public TokenProvider(string clientId, string tenantId, string redirectUri, string[] scopes)
{
_pcaOptions = new PublicClientApplicationOptions
{
ClientId = clientId,
TenantId = tenantId,
RedirectUri = redirectUri
};
_scopes = scopes;
}
public async Task<OAuthToken> GetAccessTokenAsync(bool ignoreExistingToken = false, CancellationToken cancellationToken = default)
{
var pca = PublicClientApplicationBuilder
.CreateWithApplicationOptions(_pcaOptions).Build();
try
{
var result = await pca.AcquireTokenInteractive(_scopes)
.WithUseEmbeddedWebView(false)
.ExecuteAsync(cancellationToken);
return new OAuthToken(result.AccessToken);
}
catch (MsalException ex)
{
Console.WriteLine($"Error acquiring access token: {ex}");
}
catch (Exception ex)
{
Console.WriteLine($"Error: {ex}");
}
return null;
}
public void Dispose()
{
}
}
Управление на асинхронни операции
Прекъсване на TAP метод
Започвайки от .NET Framework 4.5, можете да използвате асинхронни методи, реализирани според модела TAP. Следният фрагмент от код показва как да добавите множество съобщения, използвайки метод, базиран на задача, наречен AppendMessagesAsync и след това прекъснете този процес след известно време.
// For complete examples and data files, please go to https://github.com/aspose-email/Aspose.Email-for-.NET
List<MailMessage> mailMessages = new List<MailMessage>();
// create mail messages
for (int i = 0; i < 100; i++)
mailMessages.Add(new MailMessage(senderEmail, receiverEmail, $"Message #{i}", "Text"));
using (ImapClient client = new ImapClient(host, 993, senderEmail, password, SecurityOptions.SSLImplicit))
{
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
Exception exception = null;
ThreadPool.QueueUserWorkItem(delegate
{
try
{
// start uploading the messages
var task = client.AppendMessagesAsync(mailMessages, cancellationTokenSource.Token);
AppendMessagesResult appendMessagesResult = task.GetAwaiter().GetResult();
Console.WriteLine("All messages have been appended.");
}
catch (Exception e)
{
exception = e;
}
finally
{
autoResetEvent.Set();
}
});
Thread.Sleep(5000);
// stop uploading the messages
cancellationTokenSource.Cancel();
autoResetEvent.WaitOne();
foreach (MailMessage mailMessage in mailMessages)
mailMessage.Dispose();
if (exception is OperationCanceledException)
Console.WriteLine("Operation has been interrupted: " + exception.Message);
}
Отменяне на асинхронни операции
Понякога може да се наложи спиране на асинхронни операции. За тази цел библиотеката ни предлага отменяне на асинхронни операции чрез използване на параметъра CancellationToken. При извикване на асинхронен метод, който поддържа отменяне, можете да предадете екземпляр на CancellationToken като параметър. CancellationToken се използва за сигнализиране и контрол на отменянето на операцията.
За да активирате отменяне, първо трябва да създадете екземпляр на CancellationTokenSource, който предоставя CancellationToken. След това предайте CancellationToken към асинхронния метод, позволявайки му да проверява заявки за отменяне по време на изпълнението.
Ето пример, който демонстрира отменяне с използване на CancellationToken:
CancellationTokenSource tokenSource = new CancellationTokenSource();
AppendMessagesResult appendMessagesResult = null;
AutoResetEvent autoResetEvent = new AutoResetEvent(false);
ThreadPool.QueueUserWorkItem(delegate(object state)
{
try
{
appendMessagesResult = imapClient.AppendMessagesAsync(mmList, tokenSource.Token).GetAwaiter().GetResult();
}
catch (Exception ex)
{
}
finally
{
autoResetEvent.Set();
}
});
tokenSource.Cancel();
autoResetEvent.WaitOne();