// Load items using the specified loader internal void LoadItems( IPackageItemLoader loader, string loadingMessage, INuGetUILogger logger, Task <SearchResult <IPackageSearchMetadata> > searchResultTask, CancellationToken token) { _loader = loader; _logger = logger; _initialSearchResultTask = searchResultTask; _loadingStatusIndicator.Reset(loadingMessage); _loadingStatusBar.Visibility = Visibility.Hidden; _loadingStatusBar.Reset(loadingMessage, loader.IsMultiSource); var selectedPackageItem = SelectedPackageItem; _itemsLock.Wait(); try { ClearPackageList(); } finally { _itemsLock.Release(); } _selectedCount = 0; // triggers the package list loader LoadItems(selectedPackageItem, token); }
// Load items using the specified loader internal void LoadItems( IPackageItemLoader loader, string loadingMessage, INuGetUILogger logger, Task <SearchResult <IPackageSearchMetadata> > searchResultTask, CancellationToken token) { if (loader == null) { throw new ArgumentNullException(nameof(loader)); } if (string.IsNullOrEmpty(loadingMessage)) { throw new ArgumentException(Strings.Argument_Cannot_Be_Null_Or_Empty, nameof(loadingMessage)); } if (searchResultTask == null) { throw new ArgumentNullException(nameof(searchResultTask)); } token.ThrowIfCancellationRequested(); _loader = loader; _logger = logger; _initialSearchResultTask = searchResultTask; _loadingStatusIndicator.Reset(loadingMessage); _loadingStatusBar.Visibility = Visibility.Hidden; _loadingStatusBar.Reset(loadingMessage, loader.IsMultiSource); var selectedPackageItem = SelectedPackageItem; _itemsLock.Wait(); try { ClearPackageList(); } finally { _itemsLock.Release(); } _selectedCount = 0; // triggers the package list loader LoadItems(selectedPackageItem, token); }
// Load items using the specified loader internal async Task LoadItemsAsync( IPackageItemLoader loader, string loadingMessage, INuGetUILogger logger, Task <SearchResultContextInfo> searchResultTask, CancellationToken token) { if (loader == null) { throw new ArgumentNullException(nameof(loader)); } if (string.IsNullOrEmpty(loadingMessage)) { throw new ArgumentException(Strings.Argument_Cannot_Be_Null_Or_Empty, nameof(loadingMessage)); } if (searchResultTask == null) { throw new ArgumentNullException(nameof(searchResultTask)); } token.ThrowIfCancellationRequested(); _loader = loader; _logger = logger; _initialSearchResultTask = searchResultTask; _loadingStatusIndicator.Reset(loadingMessage); _loadingStatusBar.Visibility = Visibility.Hidden; _loadingStatusBar.Reset(loadingMessage, loader.IsMultiSource); var selectedPackageItem = SelectedPackageItem; await _list.ItemsLock.ExecuteAsync(() => { ClearPackageList(); return(Task.CompletedTask); }); _selectedCount = 0; // triggers the package list loader await LoadItemsAsync(selectedPackageItem, token); }
private async Task LoadItemsCoreAsync(IPackageItemLoader currentLoader, CancellationToken token) { token.ThrowIfCancellationRequested(); var loadedItems = await LoadNextPageAsync(currentLoader, token); token.ThrowIfCancellationRequested(); // multiple loads may occur at the same time as a result of multiple instances, // makes sure we update using the relevant one. if (currentLoader == _loader) { UpdatePackageList(loadedItems, refresh: false); } token.ThrowIfCancellationRequested(); await _joinableTaskFactory.Value.RunAsync(async() => { await _joinableTaskFactory.Value.SwitchToMainThreadAsync(); _loadingStatusBar.ItemsLoaded = currentLoader.State.ItemsCount; }); token.ThrowIfCancellationRequested(); // keep waiting till completion await WaitForCompletionAsync(currentLoader, token); token.ThrowIfCancellationRequested(); if (currentLoader == _loader && !loadedItems.Any() && currentLoader.State.LoadingStatus == LoadingStatus.Ready) { UpdatePackageList(currentLoader.GetCurrent(), refresh: false); } token.ThrowIfCancellationRequested(); }
private async Task <IEnumerable <PackageItemListViewModel> > LoadNextPageAsync(IPackageItemLoader currentLoader, CancellationToken token) { var progress = new Progress <IItemLoaderState>( s => HandleItemLoaderStateChange(currentLoader, s)); // if searchResultTask is in progress then just wait for it to complete // without creating new load task if (_initialSearchResultTask != null) { token.ThrowIfCancellationRequested(); // update initial progress var cleanState = SearchResult.Empty <IPackageSearchMetadata>(); await currentLoader.UpdateStateAndReportAsync(cleanState, progress, token); var results = await _initialSearchResultTask; token.ThrowIfCancellationRequested(); // update state and progress await currentLoader.UpdateStateAndReportAsync(results, progress, token); _initialSearchResultTask = null; } else { // trigger loading await currentLoader.LoadNextAsync(progress, token); } await WaitForInitialResultsAsync(currentLoader, progress, token); return(currentLoader.GetCurrent()); }
private async Task RepopulatePackageListAsync(PackageItemListViewModel selectedPackageItem, IPackageItemLoader currentLoader, CancellationTokenSource loadCts) { await TaskScheduler.Default; var addedLoadingIndicator = false; try { // add Loading... indicator if not present if (!Items.Contains(_loadingStatusIndicator)) { Items.Add(_loadingStatusIndicator); addedLoadingIndicator = true; } await LoadItemsCoreAsync(currentLoader, loadCts.Token); await _joinableTaskFactory.Value.SwitchToMainThreadAsync(); //Any UI filter should be cleared when Loading. ClearUIFilter(); if (selectedPackageItem != null) { UpdateSelectedItem(selectedPackageItem); } } catch (OperationCanceledException) when(!loadCts.IsCancellationRequested) { loadCts.Cancel(); loadCts.Dispose(); currentLoader.Reset(); await _joinableTaskFactory.Value.SwitchToMainThreadAsync(); // The user cancelled the login, but treat as a load error in UI // So the retry button and message is displayed // Do not log to the activity log, since it is not a NuGet error _logger.Log(new LogMessage(LogLevel.Error, Resx.Resources.Text_UserCanceled)); _loadingStatusIndicator.SetError(Resx.Resources.Text_UserCanceled); _loadingStatusBar.SetCancelled(); _loadingStatusBar.Visibility = Visibility.Visible; } catch (Exception ex) when(!loadCts.IsCancellationRequested) { loadCts.Cancel(); loadCts.Dispose(); currentLoader.Reset(); // Write stack to activity log Mvs.ActivityLog.LogError(LogEntrySource, ex.ToString()); await _joinableTaskFactory.Value.SwitchToMainThreadAsync(); var errorMessage = ExceptionUtilities.DisplayMessage(ex); _logger.Log(new LogMessage(LogLevel.Error, errorMessage)); _loadingStatusIndicator.SetError(errorMessage); _loadingStatusBar.SetError(); _loadingStatusBar.Visibility = Visibility.Visible; } finally { if (_loadingStatusIndicator.Status != LoadingStatus.NoItemsFound && _loadingStatusIndicator.Status != LoadingStatus.ErrorOccurred) { // Ideally, after a search, it should report its status, and // do not keep the LoadingStatus.Loading forever. // This is a workaround. var emptyListCount = addedLoadingIndicator ? 1 : 0; if (Items.Count == emptyListCount) { _loadingStatusIndicator.Status = LoadingStatus.NoItemsFound; } else { Items.Remove(_loadingStatusIndicator); } } } UpdateCheckBoxStatus(); LoadItemsCompleted?.Invoke(this, EventArgs.Empty); }