Fixing UI thread issues with bulk operations and request queue refactoring.
This commit is contained in:
@@ -259,25 +259,48 @@ public class SynchronizationManager : ISynchronizationManager, IRecipient<Accoun
|
||||
/// <param name="accountId">Account ID to queue the request for</param>
|
||||
/// <param name="triggerSynchronization">Whether to automatically trigger synchronization after queuing the request</param>
|
||||
public async Task QueueRequestAsync(IRequestBase request, Guid accountId, bool triggerSynchronization)
|
||||
=> await QueueRequestsAsync([request], accountId, triggerSynchronization).ConfigureAwait(false);
|
||||
|
||||
public async Task QueueRequestsAsync(IEnumerable<IRequestBase> requests, Guid accountId, bool triggerSynchronization)
|
||||
{
|
||||
EnsureInitialized();
|
||||
|
||||
var requestList = requests?.Where(request => request != null).ToList() ?? [];
|
||||
if (requestList.Count == 0)
|
||||
return;
|
||||
|
||||
var synchronizer = await GetOrCreateSynchronizerAsync(accountId);
|
||||
if (synchronizer == null)
|
||||
{
|
||||
_logger.Error("Could not find or create synchronizer for account {AccountId} to queue request", accountId);
|
||||
_logger.Error("Could not find or create synchronizer for account {AccountId} to queue {RequestCount} request(s)", accountId, requestList.Count);
|
||||
return;
|
||||
}
|
||||
|
||||
_logger.Debug("Queuing request {RequestType} for account {AccountId}",
|
||||
request.GetType().Name, accountId);
|
||||
if (requestList.Count == 1)
|
||||
{
|
||||
_logger.Debug("Queuing request {RequestType} for account {AccountId}",
|
||||
requestList[0].GetType().Name, accountId);
|
||||
}
|
||||
else
|
||||
{
|
||||
var requestSummary = string.Join(", ", requestList
|
||||
.GroupBy(request => request.GetType().Name)
|
||||
.OrderBy(group => group.Key)
|
||||
.Select(group => $"{group.Key} x{group.Count()}"));
|
||||
|
||||
synchronizer.QueueRequest(request);
|
||||
_logger.Debug("Queuing {RequestCount} requests for account {AccountId}: {RequestSummary}",
|
||||
requestList.Count, accountId, requestSummary);
|
||||
}
|
||||
|
||||
foreach (var request in requestList)
|
||||
{
|
||||
synchronizer.QueueRequest(request);
|
||||
}
|
||||
|
||||
if (triggerSynchronization)
|
||||
{
|
||||
// Determine if this is a calendar or mail operation
|
||||
bool isCalendarOperation = request is ICalendarActionRequest;
|
||||
bool isCalendarOperation = requestList.All(request => request is ICalendarActionRequest);
|
||||
|
||||
if (isCalendarOperation)
|
||||
{
|
||||
|
||||
@@ -93,13 +93,11 @@ public class WinoRequestDelegator : IWinoRequestDelegator
|
||||
// Queue requests for each account and start synchronization.
|
||||
foreach (var accountGroup in accountIds)
|
||||
{
|
||||
foreach (var accountRequest in accountGroup)
|
||||
{
|
||||
await QueueRequestAsync(accountRequest, accountGroup.Key);
|
||||
}
|
||||
var groupedRequests = accountGroup.Cast<IRequestBase>().ToList();
|
||||
await QueueRequestsAsync(groupedRequests, accountGroup.Key).ConfigureAwait(false);
|
||||
|
||||
var account = accountGroup.First().Item.AssignedAccount;
|
||||
var actionItems = SynchronizationActionHelper.CreateActionItems(accountGroup, accountGroup.Key, account.Name);
|
||||
var actionItems = SynchronizationActionHelper.CreateActionItems(groupedRequests, accountGroup.Key, account.Name);
|
||||
|
||||
if (actionItems.Count > 0)
|
||||
WeakReferenceMessenger.Default.Send(new SynchronizationActionsAdded(accountGroup.Key, account.Name, actionItems));
|
||||
@@ -214,10 +212,7 @@ public class WinoRequestDelegator : IWinoRequestDelegator
|
||||
if (requestList.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (var request in requestList)
|
||||
{
|
||||
await QueueRequestAsync(request, accountId).ConfigureAwait(false);
|
||||
}
|
||||
await QueueRequestsAsync(requestList, accountId).ConfigureAwait(false);
|
||||
|
||||
await SendSyncActionsAddedAsync(requestList, accountId).ConfigureAwait(false);
|
||||
await QueueSynchronizationAsync(accountId).ConfigureAwait(false);
|
||||
@@ -274,7 +269,12 @@ public class WinoRequestDelegator : IWinoRequestDelegator
|
||||
private async Task QueueRequestAsync(IRequestBase request, Guid accountId)
|
||||
{
|
||||
// Don't trigger synchronization for individual requests - we'll trigger it once for all requests
|
||||
await SynchronizationManager.Instance.QueueRequestAsync(request, accountId, triggerSynchronization: false);
|
||||
await SynchronizationManager.Instance.QueueRequestAsync(request, accountId, triggerSynchronization: false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private async Task QueueRequestsAsync(IEnumerable<IRequestBase> requests, Guid accountId)
|
||||
{
|
||||
await SynchronizationManager.Instance.QueueRequestsAsync(requests, accountId, triggerSynchronization: false).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private Task QueueSynchronizationAsync(Guid accountId)
|
||||
|
||||
@@ -54,6 +54,10 @@ public class WinoRequestProcessor : IWinoRequestProcessor
|
||||
{
|
||||
var action = preperationRequest.Action;
|
||||
var moveTargetStructure = preperationRequest.MoveTargetFolder;
|
||||
var mailItems = preperationRequest.MailItems?.Where(item => item != null).ToList() ?? [];
|
||||
|
||||
if (mailItems.Count == 0)
|
||||
return [];
|
||||
|
||||
// Ask confirmation for permanent delete operation.
|
||||
// Drafts are always hard deleted without any protection.
|
||||
@@ -78,12 +82,12 @@ public class WinoRequestProcessor : IWinoRequestProcessor
|
||||
// Handle the case when user is trying to move multiple mails that belong to different accounts.
|
||||
// We can't handle this with only 1 picker dialog.
|
||||
|
||||
bool isInvalidMoveTarget = preperationRequest.MailItems.Select(a => a.AssignedAccount.Id).Distinct().Count() > 1;
|
||||
bool isInvalidMoveTarget = mailItems.Select(a => a.AssignedAccount.Id).Distinct().Count() > 1;
|
||||
|
||||
if (isInvalidMoveTarget)
|
||||
throw new InvalidMoveTargetException(InvalidMoveTargetReason.MultipleAccounts);
|
||||
|
||||
var accountId = preperationRequest.MailItems.FirstOrDefault().AssignedAccount.Id;
|
||||
var accountId = mailItems[0].AssignedAccount.Id;
|
||||
|
||||
moveTargetStructure = await _dialogService.PickFolderAsync(accountId, PickFolderReason.Move, _folderService);
|
||||
|
||||
@@ -94,7 +98,7 @@ public class WinoRequestProcessor : IWinoRequestProcessor
|
||||
var requests = new List<IMailActionRequest>();
|
||||
|
||||
// TODO: Fix: Collection was modified; enumeration operation may not execute
|
||||
foreach (var item in preperationRequest.MailItems.ToList())
|
||||
foreach (var item in mailItems)
|
||||
{
|
||||
var singleRequest = await GetSingleRequestAsync(item, action, moveTargetStructure, preperationRequest.ToggleExecution);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user