private async Task RunDownloadsAsync()
        {
            // Create a downloader and associate all its downloads with the transfer group used for
            // this scenario.
            BackgroundDownloader downloader = new BackgroundDownloader();

            downloader.TransferGroup = reorderGroup;

            // Validating the URI is required since it was received from an untrusted source (user
            // input).
            // The URI is validated by calling Uri.TryCreate() that will return 'false' for strings
            // that are not valid URIs.
            // Note that when enabling the text box users may provide URIs to machines on the
            // intranet that require the "Private Networks (Client and Server)" capability.
            string remoteAddress = remoteAddressField.Text.Trim();
            Uri    tmpUri;

            if (!Uri.TryCreate(remoteAddress, UriKind.Absolute, out tmpUri))
            {
                rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage);
                return;
            }

            string fileName = fileNameField.Text.Trim();

            if (string.IsNullOrWhiteSpace(fileName))
            {
                rootPage.NotifyUser("A local file name is required.", NotifyType.ErrorMessage);
                return;
            }

            // Try to create some downloads.
            DownloadOperation[] downloads = new DownloadOperation[NumDownloads];
            try
            {
                for (int i = 0; i < NumDownloads; i++)
                {
                    string currRemoteAddress = $"{remoteAddress}?id={i}";
                    string currFileName      = $"{i}.{fileName}";
                    downloads[i] = await CreateDownload(downloader, currRemoteAddress, currFileName);
                }
            }
            catch (FileNotFoundException ex)
            {
                rootPage.NotifyUser($"Error while creating file: {ex.Message}", NotifyType.ErrorMessage);
                return;
            }

            // Once all downloads have been created, start them.
            Task[] downloadTasks = new Task[downloads.Length];
            downloadCollection.Clear();
            for (int i = 0; i < downloads.Length; i++)
            {
                DownloadOperationItem item = new DownloadOperationItem(downloads[i]);
                downloadTasks[i] = DownloadAsync(item);
                downloadCollection.Add(item);
            }

            await Task.WhenAll(downloadTasks);
        }
        private async Task DownloadAsync(DownloadOperationItem item)
        {
            Progress <DownloadOperation> progressCallback = new Progress <DownloadOperation>(
                (operation) => DownloadProgress(item));

            try
            {
                await item.download.StartAsync().AsTask(progressCallback);

                item.stateText = item.download.Progress.Status.ToString();
                rootPage.NotifyUser(
                    $"Downloading {item.download.ResultFile.Name} completed.",
                    NotifyType.StatusMessage);
            }
            catch (Exception ex)
            {
                // Ignore canceled downloads since they are not displayed.
                if (item.download.Progress.Status != BackgroundTransferStatus.Canceled)
                {
                    // Ensure that we reach 100% even for errors.
                    item.percentComplete = 100;
                    item.stateText       = item.download.Progress.Status.ToString();
                    if (!IsWebException("Execution error", ex, item.download))
                    {
                        throw;
                    }
                }
            }
        }
        private void MakeCurrent_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            DownloadOperationItem item = button.DataContext as DownloadOperationItem;

            // Make the selected operation current.
            item.download.MakeCurrentInTransferGroup();
        }
        private void DownloadProgress(DownloadOperationItem item)
        {
            BackgroundDownloadProgress currentProgress = item.download.Progress;
            BackgroundTransferStatus   status          = currentProgress.Status;
            int percentComplete = 0;

            if (currentProgress.TotalBytesToReceive > 0)
            {
                percentComplete = (int)((currentProgress.BytesReceived * 100) / currentProgress.TotalBytesToReceive);
            }

            var ignore = this.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
            {
                item.stateText       = status.ToString();
                item.percentComplete = percentComplete;
            });
        }