private async Task UpdateNavigationStack(List <ScreenInstance <TViewModel> > newNavigationStack) { lock (_mutex) { if (_navigationInProgress != null && !_navigationInProgress.IsFinished) { _navigationInProgress.Cancel(); _navigationStack.Clear(); _navigationStack.AddRange(_navigationInProgress.StackBeforeNavigation); } _navigationInProgress = null; } _navigationInProgress = new NavigationInProgress <TViewModel>(_navigationStack.ToArray()); var navigationOperation = new NavigationOperation <TViewModel>(); int commonIndexLimit = 0; for (; commonIndexLimit < newNavigationStack.Count && commonIndexLimit < _navigationStack.Count && newNavigationStack[commonIndexLimit] == _navigationStack[commonIndexLimit]; ++commonIndexLimit) { } //generate pop instructions for (int i = _navigationStack.Count - 1; i >= commonIndexLimit; i--) { navigationOperation.Add(new PopAction <TViewModel>(_navigationStack[i])); } _navigationStack.RemoveRange(commonIndexLimit, _navigationStack.Count - commonIndexLimit); //generate push instructions if (_navigationStack.Capacity < newNavigationStack.Count) { _navigationStack.Capacity = newNavigationStack.Count + 3; //Why 3 ? because we could use some margin and 3 is a nice small number ! } for (int i = commonIndexLimit; i < newNavigationStack.Count; ++i) { navigationOperation.Add(new PushAction <TViewModel>(newNavigationStack[i])); _navigationStack.Add(newNavigationStack[i]); } await _presenterService.UpdateNavigation(navigationOperation, _navigationInProgress); }