Example #1
0
        private void IdleLoop(IdleState idle)
        {
            lock (idle.Client.SyncRoot) {
                // Note: since the IMAP server will drop the connection after 30 minutes, we must loop sending IDLE commands that
                // last ~29 minutes or until the user has requested that they do not want to IDLE anymore.
                // For GMail, we use a 9 minute interval because they do not seem to keep the connection alive for more than ~10 minutes.
                while (!idle.IsCancellationRequested)
                {
                    using (var timeout = new CancellationTokenSource(TimeSpan.FromMinutes(_imapClientCanIdle ? 9 : 1))) {
                        try {
                            // We set the timeout source so that if the idle.DoneToken is cancelled, it can cancel the timeout
                            idle.SetTimeoutSource(timeout);

                            if (_imapClientCanIdle)
                            {
                                // The Idle() method will not return until the timeout has elapsed or idle.CancellationToken is cancelled
                                idle.Client.Idle(timeout.Token);
                            }
                            else
                            {
                                // The IMAP server does not support IDLE, so send a NOOP command instead
                                idle.Client.NoOp(idle.DoneToken);

                                // Wait for the timeout to elapse or the cancellation token to be cancelled
                                WaitHandle.WaitAny(new[] {
                                    timeout.Token.WaitHandle, idle.DoneToken.WaitHandle
                                });
                            }
                        } finally {
                            // we will dispose timeout, dont throw an exeption because we are trying to cancel it
                            idle.SetTimeoutSource(null);
                        }

                        if (timeout.IsCancellationRequested)
                        {
                            _config.Tracer?.TraceVerbose($"Idle timed out, looping", $"{this}");
                        }
                    }
                }
            }
        }
Example #2
0
File: Mail.cs Project: Bitz/OwO_Bot
        static void IdleLoop(object state)
        {
            IdleState idle = (IdleState)state;

            lock (idle.Client.SyncRoot)
            {
                // Note: since the IMAP server will drop the connection after 30 minutes, we must loop sending IDLE commands that
                // last ~29 minutes or until the user has requested that they do not want to IDLE anymore.
                //
                // For GMail, we use a 9 minute interval because they do not seem to keep the connection alive for more than ~10 minutes.
                while (!idle.IsCancellationRequested)
                {
                    using (var timeout = new CancellationTokenSource(new TimeSpan(0, 9, 0)))
                    {
                        try
                        {
                            // We set the timeout source so that if the idle.DoneToken is cancelled, it can cancel the timeout
                            idle.SetTimeoutSource(timeout);

                            if (idle.Client.Capabilities.HasFlag(ImapCapabilities.Idle))
                            {
                                // The Idle() method will not return until the timeout has elapsed or idle.CancellationToken is cancelled
                                idle.Client.Idle(timeout.Token, idle.CancellationToken);
                            }
                            else
                            {
                                // The IMAP server does not support IDLE, so send a NOOP command instead
                                idle.Client.NoOp(idle.CancellationToken);

                                // Wait for the timeout to elapse or the cancellation token to be cancelled
                                WaitHandle.WaitAny(new[] { timeout.Token.WaitHandle, idle.CancellationToken.WaitHandle });
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            // This means that idle.CancellationToken was cancelled, not the DoneToken nor the timeout.
                            break;
                        }
                        catch (ImapProtocolException)
                        {
                            // The IMAP server sent garbage in a response and the ImapClient was unable to deal with it.
                            // This should never happen in practice, but it's probably still a good idea to handle it.
                            //
                            // Note: an ImapProtocolException almost always results in the ImapClient getting disconnected.
                            break;
                        }
                        catch (ImapCommandException)
                        {
                            // The IMAP server responded with "NO" or "BAD" to either the IDLE command or the NOOP command.
                            // This should never happen... but again, we're catching it for the sake of completeness.
                            break;
                        }
                        finally
                        {
                            // We're about to Dispose() the timeout source, so set it to null.
                            idle.SetTimeoutSource(null);
                        }
                    }
                }
            }
        }