Как выполнять асинхронные операции IMAP с электронными письмами

Асинхронные операции с ImapClient

Работа с сообщениями может выполняться асинхронно с использованием Aspose.Email ImapClient. Эта статья показывает асинхронное получение сообщений из почтового ящика. Она также демонстрирует, как перечислять сообщения, задавая критерии поиска, используя MailQuery. Будет показано отдельно, как прервать операцию с электронными письмами, запущенную по шаблону асинхронных задач (TAP) метод.

Асинхронное получение сообщений

Ниже показан фрагмент кода, демонстрирующий, как асинхронно получать сообщения.

Список сообщений асинхронно с MailQuery

Этот MailQuery класс может использоваться для указания критериев поиска при асинхронном получении указанного списка сообщений, как показано в следующем примере кода.

Отправка сообщений асинхронно

Отправка электронных писем асинхронно очень удобна, поскольку процесс не блокирует выполнение программы или потока. Вместо того чтобы ждать отправки письма перед выполнением других задач, программа может продолжать работать, пока письмо отправляется в фоновом режиме.

Следующие возможности помогут вам реализовать асинхронную отправку в вашем проекте:

  • IAsyncImapClient - Позволяет приложениям получать доступ к сообщениям и управлять ими, используя протокол IMAP (Internet Message Access Protocol).

  • 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();