Мониторинг нескольких почтовых ящиков IMAP одновременно C# - PullRequest
0 голосов
/ 20 января 2020

У меня есть веб-приложение .NE | T Core 3, которому нужно одновременно отслеживать тысячи почтовых ящиков. Мне нужно действовать по электронной почте, как только они приходят. Я создал фоновую службу, которая зацикливается на почтовых ящиках для отслеживания, а затем создает задачу для каждого почтового ящика, работающего на протяжении всей программы. Ссылка на задачу отбрасывается в l oop, но передается токен отмены, чтобы очистить обработчики событий и закрыть соединение, когда приложение останавливается. Я использую MailKit для мониторинга почтовых ящиков с помощью клиента IMAP IDLE , см. Здесь .

foreach (var mailAccount in mailAccountsToMonitor)
{
    // ConcurrentDictionary
    if (mailAccountMonitorTasks.ContainsKey(mailAccount.Id)) continue;
    // NOT awaiting the result as these tasks run indefinitely and won't finish until the CancellationToken is cancelled
    _ = MonitorMailAccount(mailAccount, cancellationToken);
}

У меня есть метод asyn c, который вызывается при поступлении сообщения из почтового ящика. Это добавляет почтовый элемент в базу данных и выполняет некоторые другие небольшие задачи. Я пытался сохранить небольшой размер этого метода.

private async Task OnMessagesAddedAsync(object sender, MessagesAddedEventArgs args)
{
    // perform database insert and other conditional logic
}

Приведенный выше метод прикреплен как обработчик событий для незанятого клиента следующим образом: idleClient.MessagesAddedAsync += OnMessagesAddedAsync; Я использую асин * c версию события делегат в незанятом клиенте: public event Func<object, MessagesAddedEventArgs, Task> MessagesAddedAsync;

Меня беспокоит то, что это не масштабируется до тысяч почтовых ящиков, и я уже начинаю сталкиваться со странными проблемами - хотя, возможно, это связано с отсутствием у меня глубокие знания о многопоточности, а не о проблеме с этим дизайном?

Как правильно выполнять тысячи долгосрочных событийно-управляемых задач, не сталкиваясь с такими вещами, как исчерпание пула потоков, исключения сокетов и баз данных и т. д. c? Есть ли лучший способ разработать это, чем у меня уже есть?

...