MailKit: ImapClient.Idle is not cancelled
Describe the bug We observe that sometimes ImapClient.Idle is not cancelled when doneToken and cancellationToken are cancelled. We first cancel doneToken and then cancellationToken as stated in the documentation.
It is not reproduced every time. We noticed that this happens when computer is waking up from sleep and ImapClient was in idle when computer went to sleep. Probably during the computer sleep server dropped the socket because of timeout on the server side, I think this might be related.
Platform (please complete the following information):
- Windows 10
- .NET Framework 4.8
- MailKit Version - checkout at https://github.com/jstedfast/MailKit/commit/adc0aecb1a2aff67418cbd38cf968a5593cb4828
Additional information
ImapClient.Idle call stack after tokens cancellation
ntdll.dll!00007ffb6abdc0f4() Unknown mswsock.dll!00007ffb672782ed() Unknown mswsock.dll!00007ffb67278032() Unknown ws2_32.dll!00007ffb6aa01920() Unknown System.ni.dll!00007ffb38be12b2() Unknown [Managed to Native Transition] System.dll!System.Net.Sockets.Socket.Receive(byte[] buffer, int offset, int size, System.Net.Sockets.SocketFlags socketFlags, out System.Net.Sockets.SocketError errorCode) Unknown MailKit.dll!MailKit.Net.NetworkStream.Read(byte[] buffer, int offset, int count) Unknown System.dll!System.Net.FixedSizeReader.ReadPacket(byte[] buffer, int offset, int count) Unknown System.dll!System.Net.Security._SslStream.StartFrameHeader(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest) Unknown System.dll!System.Net.Security._SslStream.StartReading(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest) Unknown System.dll!System.Net.Security._SslStream.ProcessRead(byte[] buffer, int offset, int count, System.Net.AsyncProtocolRequest asyncRequest) Unknown System.dll!System.Net.Security.SslStream.Read(byte[] buffer, int offset, int count) Unknown MailKit.dll!MailKit.Net.Imap.ImapStream.ReadAheadAsync(int atleast, bool doAsync, System.Threading.CancellationToken cancellationToken) Unknown mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<int>.Start<MailKit.Net.Imap.ImapStream.<ReadAheadAsync>d__59>(ref MailKit.Net.Imap.ImapStream.<ReadAheadAsync>d__59 stateMachine) Unknown MailKit.dll!MailKit.Net.Imap.ImapStream.ReadAheadAsync(int atleast, bool doAsync, System.Threading.CancellationToken cancellationToken) Unknown MailKit.dll!MailKit.Net.Imap.ImapStream.ReadTokenAsync(string specials, bool doAsync, System.Threading.CancellationToken cancellationToken) Unknown mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.__Canon>.Start<MailKit.Net.Imap.ImapStream.<ReadTokenAsync>d__74>(ref MailKit.Net.Imap.ImapStream.<ReadTokenAsync>d__74 stateMachine) Unknown MailKit.dll!MailKit.Net.Imap.ImapStream.ReadTokenAsync(string specials, bool doAsync, System.Threading.CancellationToken cancellationToken) Unknown MailKit.dll!MailKit.Net.Imap.ImapCommand.StepAsync(bool doAsync) Unknown mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<bool>.Start<MailKit.Net.Imap.ImapCommand.<StepAsync>d__83>(ref MailKit.Net.Imap.ImapCommand.<StepAsync>d__83 stateMachine) Unknown MailKit.dll!MailKit.Net.Imap.ImapCommand.StepAsync(bool doAsync) Unknown MailKit.dll!MailKit.Net.Imap.ImapEngine.IterateAsync(bool doAsync) Unknown mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<MailKit.Net.Imap.ImapEngine.<IterateAsync>d__170>(ref MailKit.Net.Imap.ImapEngine.<IterateAsync>d__170 stateMachine) Unknown MailKit.dll!MailKit.Net.Imap.ImapEngine.IterateAsync(bool doAsync) Unknown MailKit.dll!MailKit.Net.Imap.ImapEngine.RunAsync(MailKit.Net.Imap.ImapCommand ic, bool doAsync) Unknown mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<MailKit.Net.Imap.ImapEngine.<RunAsync>d__171>(ref MailKit.Net.Imap.ImapEngine.<RunAsync>d__171 stateMachine) Unknown MailKit.dll!MailKit.Net.Imap.ImapEngine.RunAsync(MailKit.Net.Imap.ImapCommand ic, bool doAsync) Unknown MailKit.dll!MailKit.Net.Imap.ImapClient.IdleAsync(System.Threading.CancellationToken doneToken, bool doAsync, System.Threading.CancellationToken cancellationToken) Unknown mscorlib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start<MailKit.Net.Imap.ImapClient.<IdleAsync>d__99>(ref MailKit.Net.Imap.ImapClient.<IdleAsync>d__99 stateMachine) Unknown MailKit.dll!MailKit.Net.Imap.ImapClient.IdleAsync(System.Threading.CancellationToken doneToken, bool doAsync, System.Threading.CancellationToken cancellationToken) Unknown MailKit.dll!MailKit.Net.Imap.ImapClient.Idle(System.Threading.CancellationToken doneToken, System.Threading.CancellationToken cancellationToken) Unknown
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 22 (22 by maintainers)
Commits related to this issue
- Send the IMAP IDLE DONE command asynchronously May help fix issue #1025 — committed to jstedfast/MailKit by jstedfast 4 years ago
- Don't bother with Socket.Shutdown() when cancelling network I/O Instead, call Socket.Disconnect (false). May fix issue #1025 — committed to jstedfast/MailKit by jstedfast 4 years ago
- Revert back to sending the IMAP IDLE DONE command synchronously Sending the DONE command async causes a hang. Partial fix for issue #1025 — committed to jstedfast/MailKit by jstedfast 4 years ago
- Make sure the ImapStream is not null (can be null if user calls Disconnect() causing IDLE to abort) Fixes issue #1025 — committed to jstedfast/MailKit by jstedfast 4 years ago
Thanks. I’ll try them and will let you know the outcome.