diff --git a/MailKit/Net/Imap/ImapEngine.cs b/MailKit/Net/Imap/ImapEngine.cs index 3d3be34771..5441e23215 100644 --- a/MailKit/Net/Imap/ImapEngine.cs +++ b/MailKit/Net/Imap/ImapEngine.cs @@ -2450,7 +2450,7 @@ internal void ProcessUntaggedResponse (CancellationToken cancellationToken) if (QuirksMode == ImapQuirksMode.Yandex && !current.Logout) current.Status = ImapCommandStatus.Complete; } else if (atom.Equals ("CAPABILITY", StringComparison.OrdinalIgnoreCase)) { - UpdateCapabilitiesAsync (ImapTokenType.Eoln, doAsync: false, cancellationToken).GetAwaiter ().GetResult (); + UpdateCapabilities (ImapTokenType.Eoln, cancellationToken); // read the eoln token ReadToken (cancellationToken); @@ -2516,7 +2516,7 @@ internal void ProcessUntaggedResponse (CancellationToken cancellationToken) //if (number == 0) // throw UnexpectedToken ("Syntax error in untagged FETCH response. Unexpected message index: 0"); - folder.OnUntaggedFetchResponse (this, (int) number - 1, doAsync: false, cancellationToken).GetAwaiter ().GetResult (); + folder.OnUntaggedFetchResponse (this, (int) number - 1, cancellationToken); } else if (atom.Equals ("RECENT", StringComparison.OrdinalIgnoreCase)) { folder.OnRecent ((int) number); } else { @@ -2545,7 +2545,7 @@ internal void ProcessUntaggedResponse (CancellationToken cancellationToken) token = ReadToken (cancellationToken); AssertToken (token, ImapTokenType.Eoln, "Syntax error in untagged LIST response. {0}", token); } else if (atom.Equals ("VANISHED", StringComparison.OrdinalIgnoreCase) && folder != null) { - folder.OnVanishedAsync (this, doAsync: false, cancellationToken).GetAwaiter ().GetResult (); + folder.OnVanished (this, cancellationToken); SkipLine (cancellationToken); } else { // don't know how to handle this... eat it? @@ -2603,7 +2603,7 @@ internal async Task ProcessUntaggedResponseAsync (CancellationToken cancellation if (QuirksMode == ImapQuirksMode.Yandex && !current.Logout) current.Status = ImapCommandStatus.Complete; } else if (atom.Equals ("CAPABILITY", StringComparison.OrdinalIgnoreCase)) { - await UpdateCapabilitiesAsync (ImapTokenType.Eoln, doAsync: true, cancellationToken).ConfigureAwait (false); + await UpdateCapabilitiesAsync (ImapTokenType.Eoln, cancellationToken).ConfigureAwait (false); // read the eoln token await ReadTokenAsync (cancellationToken).ConfigureAwait (false); @@ -2669,7 +2669,7 @@ internal async Task ProcessUntaggedResponseAsync (CancellationToken cancellation //if (number == 0) // throw UnexpectedToken ("Syntax error in untagged FETCH response. Unexpected message index: 0"); - await folder.OnUntaggedFetchResponse (this, (int) number - 1, doAsync: true, cancellationToken).ConfigureAwait (false); + await folder.OnUntaggedFetchResponseAsync (this, (int) number - 1, cancellationToken).ConfigureAwait (false); } else if (atom.Equals ("RECENT", StringComparison.OrdinalIgnoreCase)) { folder.OnRecent ((int) number); } else { @@ -2698,7 +2698,7 @@ internal async Task ProcessUntaggedResponseAsync (CancellationToken cancellation token = await ReadTokenAsync (cancellationToken).ConfigureAwait (false); AssertToken (token, ImapTokenType.Eoln, "Syntax error in untagged LIST response. {0}", token); } else if (atom.Equals ("VANISHED", StringComparison.OrdinalIgnoreCase) && folder != null) { - await folder.OnVanishedAsync (this, doAsync: true, cancellationToken).ConfigureAwait (false); + await folder.OnVanishedAsync (this, cancellationToken).ConfigureAwait (false); await SkipLineAsync (cancellationToken).ConfigureAwait (false); } else { // don't know how to handle this... eat it? diff --git a/MailKit/Net/Imap/ImapFolder.cs b/MailKit/Net/Imap/ImapFolder.cs index c5f69d3f83..bfac481a8e 100644 --- a/MailKit/Net/Imap/ImapFolder.cs +++ b/MailKit/Net/Imap/ImapFolder.cs @@ -328,7 +328,12 @@ static string SelectOrExamine (FolderAccess access) static Task UntaggedQResyncFetchHandler (ImapEngine engine, ImapCommand ic, int index, bool doAsync) { - return ic.Folder.OnUntaggedFetchResponse (engine, index, doAsync, ic.CancellationToken); + if (doAsync) + return ic.Folder.OnUntaggedFetchResponseAsync (engine, index, ic.CancellationToken); + + ic.Folder.OnUntaggedFetchResponse (engine, index, ic.CancellationToken); + + return Task.CompletedTask; } ImapCommand QueueOpenCommand (FolderAccess access, uint uidValidity, ulong highestModSeq, IList uids, CancellationToken cancellationToken) @@ -6133,16 +6138,18 @@ void OnFetchAsyncCompleted (MessageSummary message) OnMessageSummaryFetched (message); } - internal Task OnUntaggedFetchResponse (ImapEngine engine, int index, bool doAsync, CancellationToken cancellationToken) + internal void OnUntaggedFetchResponse (ImapEngine engine, int index, CancellationToken cancellationToken) { var message = new MessageSummary (this, index); - if (doAsync) - return ParseSummaryItemsAsync (engine, message, OnFetchAsyncCompleted, cancellationToken); - ParseSummaryItems (engine, message, OnFetchAsyncCompleted, cancellationToken); + } - return Task.CompletedTask; + internal Task OnUntaggedFetchResponseAsync (ImapEngine engine, int index, CancellationToken cancellationToken) + { + var message = new MessageSummary (this, index); + + return ParseSummaryItemsAsync (engine, message, OnFetchAsyncCompleted, cancellationToken); } internal void OnRecent (int count) @@ -6155,15 +6162,27 @@ internal void OnRecent (int count) OnRecentChanged (); } - internal async Task OnVanishedAsync (ImapEngine engine, bool doAsync, CancellationToken cancellationToken) + void OnVanished (bool earlier, ImapToken token) + { + var vanished = ImapEngine.ParseUidSet (token, UidValidity, out _, out _, ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "VANISHED", token); + + OnMessagesVanished (new MessagesVanishedEventArgs (vanished, earlier)); + + if (!earlier) { + Count -= vanished.Count; + + OnCountChanged (); + } + } + + internal void OnVanished (ImapEngine engine, CancellationToken cancellationToken) { - var token = await engine.ReadTokenAsync (doAsync, cancellationToken).ConfigureAwait (false); - UniqueIdSet vanished; + var token = engine.ReadToken (cancellationToken); bool earlier = false; if (token.Type == ImapTokenType.OpenParen) { do { - token = await engine.ReadTokenAsync (doAsync, cancellationToken).ConfigureAwait (false); + token = engine.ReadToken (cancellationToken); if (token.Type == ImapTokenType.CloseParen) break; @@ -6176,18 +6195,36 @@ internal async Task OnVanishedAsync (ImapEngine engine, bool doAsync, Cancellati earlier = true; } while (true); - token = await engine.ReadTokenAsync (doAsync, cancellationToken).ConfigureAwait (false); + token = engine.ReadToken (cancellationToken); } - vanished = ImapEngine.ParseUidSet (token, UidValidity, out _, out _, ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "VANISHED", token); + OnVanished (earlier, token); + } - OnMessagesVanished (new MessagesVanishedEventArgs (vanished, earlier)); + internal async Task OnVanishedAsync (ImapEngine engine, CancellationToken cancellationToken) + { + var token = await engine.ReadTokenAsync (cancellationToken).ConfigureAwait (false); + bool earlier = false; - if (!earlier) { - Count -= vanished.Count; + if (token.Type == ImapTokenType.OpenParen) { + do { + token = await engine.ReadTokenAsync (cancellationToken).ConfigureAwait (false); - OnCountChanged (); + if (token.Type == ImapTokenType.CloseParen) + break; + + ImapEngine.AssertToken (token, ImapTokenType.Atom, ImapEngine.GenericUntaggedResponseSyntaxErrorFormat, "VANISHED", token); + + var atom = (string) token.Value; + + if (atom.Equals ("EARLIER", StringComparison.OrdinalIgnoreCase)) + earlier = true; + } while (true); + + token = await engine.ReadTokenAsync (cancellationToken).ConfigureAwait (false); } + + OnVanished (earlier, token); } internal void UpdateAttributes (FolderAttributes attrs)