From d0b54ea44b979978cee7a9c75e4e0f32c0798abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20Kaan=20K=C3=B6se?= Date: Sun, 25 Aug 2024 02:01:08 +0200 Subject: [PATCH] Prevent delay between mail addings and better folder init cancellation. --- Wino.Core.Domain/Interfaces/IMailService.cs | 4 +-- Wino.Core/Services/MailService.cs | 9 +++++- Wino.Mail.ViewModels/MailListPageViewModel.cs | 32 ++++++++++++------- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/Wino.Core.Domain/Interfaces/IMailService.cs b/Wino.Core.Domain/Interfaces/IMailService.cs index e687ba24..0b297d89 100644 --- a/Wino.Core.Domain/Interfaces/IMailService.cs +++ b/Wino.Core.Domain/Interfaces/IMailService.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; -using MimeKit; using Wino.Core.Domain.Entities; using Wino.Core.Domain.Models.MailItem; @@ -11,7 +11,7 @@ namespace Wino.Core.Domain.Interfaces { Task GetSingleMailItemAsync(string mailCopyId, string remoteFolderId); Task GetSingleMailItemAsync(Guid uniqueMailId); - Task> FetchMailsAsync(MailListInitializationOptions options); + Task> FetchMailsAsync(MailListInitializationOptions options, CancellationToken cancellationToken = default); /// /// Deletes all mail copies for all folders. diff --git a/Wino.Core/Services/MailService.cs b/Wino.Core/Services/MailService.cs index fe9178ed..4a970593 100644 --- a/Wino.Core/Services/MailService.cs +++ b/Wino.Core/Services/MailService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading; using System.Threading.Tasks; using Microsoft.Kiota.Abstractions.Extensions; using MimeKit; @@ -193,7 +194,7 @@ namespace Wino.Core.Services return query.GetRawQuery(); } - public async Task> FetchMailsAsync(MailListInitializationOptions options) + public async Task> FetchMailsAsync(MailListInitializationOptions options, CancellationToken cancellationToken = default) { var query = BuildMailFetchQuery(options); @@ -216,6 +217,8 @@ namespace Wino.Core.Services if (!options.CreateThreads) { + cancellationToken.ThrowIfCancellationRequested(); + // Threading is disabled. Just return everything as it is. mails.Sort(options.SortingOptionType == SortingOptionType.ReceiveDate ? new DateComparer() : new NameComparer()); @@ -229,6 +232,8 @@ namespace Wino.Core.Services // Each account items must be threaded separately. foreach (var group in mails.GroupBy(a => a.AssignedAccount.Id)) { + cancellationToken.ThrowIfCancellationRequested(); + var accountId = group.Key; var groupAccount = mails.First(a => a.AssignedAccount.Id == accountId).AssignedAccount; @@ -242,6 +247,7 @@ namespace Wino.Core.Services // Almost everything already should be in cache from initial population. foreach (var mail in accountThreadedItems) { + cancellationToken.ThrowIfCancellationRequested(); await LoadAssignedPropertiesWithCacheAsync(mail, folderCache, accountCache).ConfigureAwait(false); } @@ -252,6 +258,7 @@ namespace Wino.Core.Services } threadedItems.Sort(options.SortingOptionType == SortingOptionType.ReceiveDate ? new DateComparer() : new NameComparer()); + cancellationToken.ThrowIfCancellationRequested(); return threadedItems; diff --git a/Wino.Mail.ViewModels/MailListPageViewModel.cs b/Wino.Mail.ViewModels/MailListPageViewModel.cs index 17d2e754..a09c3d67 100644 --- a/Wino.Mail.ViewModels/MailListPageViewModel.cs +++ b/Wino.Mail.ViewModels/MailListPageViewModel.cs @@ -614,8 +614,6 @@ namespace Wino.Mail.ViewModels try { - await listManipulationSemepahore.WaitAsync(); - if (ActiveFolder == null) return; // At least accounts must match. @@ -631,6 +629,8 @@ namespace Wino.Mail.ViewModels // Item should be prevented from being added to the list due to filter. if (!shouldPreventIgnoringFilter && ShouldPreventItemAdd(addedMail)) return; + await listManipulationSemepahore.WaitAsync(); + await MailCollection.AddAsync(addedMail); await ExecuteUIThread(() => { NotifyItemFoundState(); }); @@ -762,12 +762,17 @@ namespace Wino.Mail.ViewModels // Folder is changed during initialization. // Just cancel the existing one and wait for new initialization. - if (listManipulationSemepahore.CurrentCount == 0) - { - Debug.WriteLine("Canceling initialization of mails."); + //if (listManipulationSemepahore.CurrentCount == 0) + //{ + // Debug.WriteLine("Canceling initialization of mails."); + // listManipulationCancellationTokenSource.Cancel(); + // listManipulationCancellationTokenSource.Token.ThrowIfCancellationRequested(); + //} + + if (!listManipulationCancellationTokenSource.IsCancellationRequested) + { listManipulationCancellationTokenSource.Cancel(); - listManipulationCancellationTokenSource.Token.ThrowIfCancellationRequested(); } listManipulationCancellationTokenSource = new CancellationTokenSource(); @@ -794,15 +799,18 @@ namespace Wino.Mail.ViewModels SearchQuery, MailCollection.MailCopyIdHashSet); - var items = await _mailService.FetchMailsAsync(initializationOptions).ConfigureAwait(false); + var items = await _mailService.FetchMailsAsync(initializationOptions, cancellationToken).ConfigureAwait(false); - // Here they are already threaded if needed. - // We don't need to insert them one by one. - // Just create VMs and do bulk insert. + if (!listManipulationCancellationTokenSource.IsCancellationRequested) + { + // Here they are already threaded if needed. + // We don't need to insert them one by one. + // Just create VMs and do bulk insert. - var viewModels = PrepareMailViewModels(items); + var viewModels = PrepareMailViewModels(items); - await ExecuteUIThread(() => { MailCollection.AddRange(viewModels, true); }); + await ExecuteUIThread(() => { MailCollection.AddRange(viewModels, true); }); + } } catch (OperationCanceledException) {