private async Task ProcessMessages() { using (var client = _settings.GetImapClient()) { ImapUtils.InitMailboxes(client, _endpointName); if (_purgeOnStartup) { ImapUtils.PurgeMailboxes(client, _endpointName); } client.Inbox.Open(FolderAccess.ReadWrite); var query = SearchQuery.SubjectContains($"NSB-MSG-{_endpointName}-"); // Listen to new messages void CheckForNewMessages(object o, EventArgs args) { _log.Debug("Mailbox count changed."); _timeoutTokenSource.Cancel(); } client.Inbox.CountChanged += CheckForNewMessages; _cancellationTokenSource = new CancellationTokenSource(); while (!_cancellationTokenSource.IsCancellationRequested) { _timeoutTokenSource = new CancellationTokenSource(TimeSpan.FromMinutes(5)); using (_timeoutTokenSource) { try { foreach (var m in client.Inbox.Search(query)) { _log.Debug($"Processing message with UID: {m}."); await ProcessMessageWithTransaction(client, m); } if (client.Capabilities.HasFlag(ImapCapabilities.Idle)) { _log.Debug("Waiting for IDLE from IMAP server."); await client.IdleAsync(_timeoutTokenSource.Token, _cancellationTokenSource.Token); } else { _log.Debug("Waiting for new messages..."); client.NoOp(_cancellationTokenSource.Token); WaitHandle.WaitAny(new[] { _timeoutTokenSource.Token.WaitHandle, _cancellationTokenSource.Token.WaitHandle }); } } catch (OperationCanceledException) { } catch (ImapProtocolException) { break; } catch (ImapCommandException) { break; } catch (Exception ex) { _log.Error(ex.Message, ex); _criticalError.Raise(ex.Message, ex); } } } } }