メールに対する非同期 IMAP 操作の実行方法

ImapClient を使用した非同期操作

Aspose.Email を使用すると、メッセージの操作を非同期で実行できます。 ImapClient. この記事では、メールボックスからメッセージを非同期で取得する方法を示します。また、検索条件を指定してメッセージを一覧表示する方法も示します。 MailQuery. タスクベースの非同期パターンで開始されたメールメッセージの操作を中断する方法が別途示されます (TAP) メソッドです。

メッセージを非同期で取得

以下のコードスニペットは、メッセージを非同期で取得する方法を示します。

MailQuery を使用したメッセージの非同期一覧取得

この MailQuery クラスは、非同期で指定されたメッセージリストを取得するための検索条件を指定するために使用でき、以下のコードサンプルに示されています。

メッセージを非同期で送信

メールを非同期で送信すると、プロセスがプログラムやスレッドの実行をブロックしないため非常に便利です。メールの送信完了を待ってから他のタスクを進める代わりに、メールがバックグラウンドで送信されている間もプログラムは継続して実行できます。

以下の機能は、プロジェクトで非同期送信を実装するのに役立ちます:

  • IAsyncImapClient - アプリケーションがインターネットメッセージアクセスプロトコル (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 は操作のキャンセルを通知および制御するために使用されます。

キャンセルを有効にするには、まず CancellationToken を提供する CancellationTokenSource インスタンスを作成する必要があります。次に、その 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();