예제 #1
0
        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);
                        }
                    }
                }
            }
        }