private void onSyncChanged(SyncProgress syncProgress) { switch (syncProgress) { case Unknown: return; case Failed: case OfflineModeDetected: var errorMessage = syncProgress == OfflineModeDetected ? FoundationResources.Offline : FoundationResources.SyncFailed; var snackbar = Snackbar.Make(coordinatorLayout, errorMessage, Snackbar.LengthLong) .SetAction(FoundationResources.TapToRetry, onRetryTapped); snackbar.SetDuration(snackbarDuration); snackbar.Show(); break; } void onRetryTapped(View view) { ViewModel.Refresh.Execute(); } }
private void postAccessibilityAnnouncementAboutSync(SyncProgress syncProgress) { string message = ""; switch (syncProgress) { case SyncProgress.Failed: message = Resources.SyncFailed; break; case SyncProgress.OfflineModeDetected: message = Resources.SyncFailedOffline; break; case SyncProgress.Synced: message = Resources.SuccessfullySyncedData; break; //These 2 are not announced case SyncProgress.Syncing: return; case SyncProgress.Unknown: return; } accessibilityService.PostAnnouncement(message); }
private void reportProgress(SyncProgress obj) { this.synchronizationContext.Post((state) => { SyncProgress progress = state as SyncProgress; syncProgressLabel.Content = progress.Message; }, obj); }
/// <summary> /// Private constructor... Use the Show() method rather /// </summary> private TaskForm() { InitializeComponent(); // Create our progress updater. We put this inside the form constructor // to capture the Synchronization Context of this thread Progress = new SyncProgress <TaskProgressUpdate>(e => ProgressChanged(e)); }
private async void syncProgressChanged(SyncProgress syncProgress) { bool hideIndicator = false; shouldRefreshOnTap = false; isSyncing = false; switch (syncProgress) { case SyncProgress.Unknown: return; case SyncProgress.Syncing: setSyncIndicatorTextAndBackground( new NSAttributedString(Resources.Syncing), syncingColor); setActivityIndicatorVisible(true); isSyncing = true; break; case SyncProgress.OfflineModeDetected: setSyncIndicatorTextAndBackground( Resources.Offline.EndingWithRefreshIcon(syncStateLabel.Font.CapHeight), offlineColor); dismissSyncBarButton.Hidden = false; setActivityIndicatorVisible(false); shouldRefreshOnTap = true; break; case SyncProgress.Synced: setSyncIndicatorTextAndBackground( Resources.SyncCompleted.EndingWithTick(syncStateLabel.Font.CapHeight), syncCompletedColor); hideIndicator = true; setActivityIndicatorVisible(false); break; case SyncProgress.Failed: setSyncIndicatorTextAndBackground( Resources.SyncFailed.EndingWithRefreshIcon(syncStateLabel.Font.CapHeight), syncFailedColor); dismissSyncBarButton.Hidden = false; setActivityIndicatorVisible(false); break; default: throw new ArgumentException(nameof(SyncProgress)); } showSyncBar(); if (!hideIndicator) { return; } await hideSyncBar(); }
private IObservable <bool> checkSynced(SyncProgress progress) { if (isLoggingOut || progress != SyncProgress.Synced) { return(Observable.Return(false)); } return(isSynced()); }
public async Task RunExample() { PhilomenaClient client = new PhilomenaClient("https://derpibooru.org"); IPhilomenaImageSearch search = client.GetImageSearch("fluttershy", o => o .WithMaxImages(5) ); Log.Information("Download query simple"); // Using download all method await search .CreateParallelDownloader(maxDownloadThreads : 8, o => o .WithImageFileDownloader(image => $"ExampleDownloads/EnumerateSearchQuery/{image.Id}.{image.Format}") ) .BeginDownload(); Log.Information("Download query with delegates, skipping existing images"); // Use a conditional downloader to skip images already downloaded // Note that filters in the search query itself are preferred since they will provide better performance. Don't use conditional downloaders for conditions like image score. await search .CreateParallelDownloader(maxDownloadThreads : 8, o => o .WithConditionalDownloader(SkipImagesAlreadyDownloaded, o => o .WithImageFileDownloader(GetFileForImage) ) ) .BeginDownload(); Log.Information("Downloading images explicitly"); // Explicitly looping over each image and saving await foreach (IPhilomenaImage image in search.BeginSearch()) { string filename = $"ExampleDownloads/EnumerateSearchQuery/{image.Id}.{image.Format}"; await image.DownloadToFile(filename); } Log.Information("Downloading with multiple threads and progress updates"); // Downloading with multiple threads and progress updates // Also skips downloaded images like before SyncProgress <PhilomenaImageSearchDownloadProgressInfo> progress = new SyncProgress <PhilomenaImageSearchDownloadProgressInfo>(DownloadProgressUpdate); await client .GetImageSearch("fluttershy", o => o .WithMaxImages(100) ) .CreateParallelDownloader(maxDownloadThreads: 8, o => o .WithConditionalDownloader(SkipImagesAlreadyDownloaded, o => o .WithImageFileDownloader(GetFileForImage) .WithImageMetadataFileDownloader(GetMetadataFileForImage) ) ) .BeginDownload(searchDownloadProgress: progress); }
//Update the progress of copying the files and folders private void UpdateProgressbarAndCheckProgress() { SyncProgress.PerformStep(); FileLeftCounter.Text = templateCountLeftText + copyCountLeft.ToString(); if (copyCountLeft <= 0) { FileLeftCounter.Text = templateCountLeftText + 0; copyCountLeft = 0; SyncProgress.Value = SyncProgress.Maximum; } }
public override async Task Download(IPhilomenaImage downloadItem, CancellationToken cancellationToken = default, IProgress <PhilomenaImageDownloadProgressInfo>?progress = null) { if (!downloadItem.IsSvgImage) { _logger.LogDebug("Cannot download SVG since image {ImageId} is not an SVG image", downloadItem.Id); return; } try { string file = _getFileForImage(downloadItem); // Create directory for image download string?imageDirectory = Path.GetDirectoryName(file); if (imageDirectory is null) { throw new DirectoryNotFoundException($"The file does not have a parent directory: {file}"); } Directory.CreateDirectory(imageDirectory); // Create stream progress info IProgress <StreamProgressInfo> streamProgress = new SyncProgress <StreamProgressInfo>(streamProgress => { progress?.Report(new PhilomenaImageDownloadProgressInfo { Current = streamProgress.BytesRead, Total = streamProgress.BytesTotal, Action = $"Downloading image {downloadItem.Id} (SVG)" }); }); // Get the download stream for the image using Stream downloadStream = await GetDownloadStream(downloadItem, cancellationToken, streamProgress, isSvgVersion : true); _logger.LogDebug("Saving SVG image {ImageId} to {File}", downloadItem.Id, file); // Write to a temp file first string tempFile = file + "." + _tempExtension; using (FileStream tempFileStream = File.OpenWrite(tempFile)) { await downloadStream.CopyToAsync(tempFileStream, cancellationToken); } // Move the temp file to the destination file File.Move(tempFile, file, overwrite: true); } catch (Exception ex) when(ex is FlurlHttpException or IOException) { _logger.LogWarning(ex, "Failed to download SVG image {ImageId}", downloadItem.Id); } } }
/// <summary> /// Try to raise a generalist progress event /// </summary> private void TryRaiseProgressEvent(SyncStage stage, string message, Dictionary <string, string> properties = null, DbConnection connection = null, DbTransaction transaction = null) { var progressEventArgs = new ProgressEventArgs(this.ProviderTypeName, stage, message, connection, transaction); if (properties != null) { progressEventArgs.Properties = properties; } SyncProgress?.Invoke(this, progressEventArgs); if (progressEventArgs.Action == ChangeApplicationAction.Rollback) { throw new RollbackException(); } }
/// <summary> /// Try to raise a generalist progress event /// </summary> private void TryRaiseProgressEvent(SyncStage stage, String message, Dictionary <String, String> properties = null) { ProgressEventArgs progressEventArgs = new ProgressEventArgs(this.ProviderTypeName, stage, message); if (properties != null) { progressEventArgs.Properties = properties; } SyncProgress?.Invoke(this, progressEventArgs); if (progressEventArgs.Action == ChangeApplicationAction.Rollback) { throw new RollbackException(); } }
private SyncProgress UseNewProgress() { var progress = new SyncProgress(); progress.ProgressUpdated += (object sender, EventArgs e) => { if (_projectDoc == null) { return; } double percentCompleted = progress.ProgressValue; if (percentCompleted >= 0) { _projectDoc.SubmitJson0OpAsync(op => op.Set(pd => pd.Sync.PercentCompleted, percentCompleted)); } }; return(progress); }
public async Task RunExample() { PhilomenaClient client = new PhilomenaClient("https://derpibooru.org"); using CancellationTokenSource cts = new CancellationTokenSource(); SyncProgress <PhilomenaImageSearchDownloadProgressInfo> searchProgress = new SyncProgress <PhilomenaImageSearchDownloadProgressInfo>(ProgressReport); // Run the download on another thread Task downloadTask = Task.Run(async() => { try { await client .GetImageSearch("fluttershy", o => o .WithMaxImages(100) ) .CreateParallelDownloader(maxDownloadThreads: 1, o => o .WithImageFileDownloader(image => Path.Join("ExampleDownloads", "PauseAndCancelImageDownload", $"{image.Id}.{image.Format}")) ) .BeginDownload(cts.Token); } catch (OperationCanceledException) { Log.Information("Download cancelled"); } }); // Wait a bit before canceling Log.Information("Downloading some images"); await Task.Delay(3000); // Cancel the download Log.Information("Cancelling the download"); cts.Cancel(); // Wait for the download thread to finish await downloadTask; Log.Information("Download ended"); }
public void ValidatesFileIsWritable() { var logs = new List <string>(); var progress = new SyncProgress(logs.Add); var projectFile = Path.Combine("TestFiles", "OtherTestProjects", "readonly.testcsproj"); var copiedProjectFile = Path.Combine("TestFiles", "OtherTestProjects", $"{nameof(ValidatesFileIsWritable)}.readonly"); if (File.Exists(copiedProjectFile)) { File.SetAttributes(copiedProjectFile, FileAttributes.Normal); File.Delete(copiedProjectFile); } try { File.Copy(projectFile, copiedProjectFile); File.SetAttributes(copiedProjectFile, FileAttributes.ReadOnly); var project = new ProjectReader(copiedProjectFile, progress).Read(); Assert.IsFalse(logs.Any(x => x.Contains("Aborting as could not write to project file"))); var writer = new ProjectWriter(); writer.Write(project, makeBackups: false, progress); Assert.IsTrue(logs.Any(x => x.Contains("Aborting as could not write to project file"))); } finally { if (File.Exists(copiedProjectFile)) { File.SetAttributes(copiedProjectFile, FileAttributes.Normal); File.Delete(copiedProjectFile); } } }
public void ValidatesFileIsWritableAfterCheckout() { var logs = new List <string>(); var progress = new SyncProgress(logs.Add); var projectFile = "TestFiles\\OtherTestProjects\\readonly.testcsproj"; var copiedProjectFile = $"TestFiles\\OtherTestProjects\\{nameof(ValidatesFileIsWritableAfterCheckout)}.readonly"; if (File.Exists(copiedProjectFile)) { File.SetAttributes(copiedProjectFile, FileAttributes.Normal); File.Delete(copiedProjectFile); } try { File.Copy(projectFile, copiedProjectFile); File.SetAttributes(copiedProjectFile, FileAttributes.ReadOnly); var project = new ProjectReader().Read(copiedProjectFile, progress); var projectWriter = new ProjectWriter(_ => { }, file => File.SetAttributes(file.FullName, FileAttributes.Normal)); projectWriter.Write(project, makeBackups: false, progress); Assert.IsFalse(logs.Any(x => x.Contains("Aborting as could not write to project file"))); } finally { if (File.Exists(copiedProjectFile)) { File.SetAttributes(copiedProjectFile, FileAttributes.Normal); File.Delete(copiedProjectFile); } } }
private void DispatchSyncProgress(long bytesLoaded, long bytesTotal, int status, string callbackId, bool keepCallback = true) { //Debug.WriteLine("DispatchSyncProgress : " + callbackId); // send a progress change event SyncProgress progEvent = new SyncProgress(bytesTotal); progEvent.BytesLoaded = bytesLoaded; int percent = (int)((bytesLoaded / (double)bytesTotal) * 100); // jump from 50 to 100 once unzip is done if (bytesLoaded != bytesTotal && status != 3) { percent = percent / 2; } string result = "{\"progress\":" + percent + ", \"status\":" + status + "}"; PluginResult plugRes = new PluginResult(PluginResult.Status.OK, result); plugRes.KeepCallback = keepCallback; plugRes.CallbackId = callbackId; DispatchCommandResult(plugRes, callbackId); }
private bool isRunningSync(SyncProgress progress) => isLoggingOut == false && progress == SyncProgress.Syncing;
public async Task BeginDownload( CancellationToken cancellationToken = default, IProgress <PhilomenaImageSearchProgressInfo>?searchProgress = null, IProgress <PhilomenaImageSearchDownloadProgressInfo>?searchDownloadProgress = null, IReadOnlyCollection <IProgress <PhilomenaImageDownloadProgressInfo> >?individualDownloadProgresses = null) { ConcurrentBag <IProgress <PhilomenaImageDownloadProgressInfo> >?availableProgress = null; if (individualDownloadProgresses is not null) { // Ensure enough progress entries are provided if (individualDownloadProgresses.Count != _maxDownloadThreads) { throw new ArgumentException($"Expected {_maxDownloadThreads} progress entries, but {individualDownloadProgresses.Count} were provided.", nameof(individualDownloadProgresses)); } // Copy progress entries to a thread safe structure availableProgress = new ConcurrentBag <IProgress <PhilomenaImageDownloadProgressInfo> >(individualDownloadProgresses); } // Track images downloaded int imagesDownloaded = 0; // The total images to download is unknown until the image search reports it int totalImages = -1; // An object to lock on for reporting the search download progress object searchDownloadProgressLock = new object(); // Wrap the image search progress to track the total number of images to download IProgress <PhilomenaImageSearchProgressInfo> wrappedSearchProgress = new SyncProgress <PhilomenaImageSearchProgressInfo>(progress => { totalImages = progress.TotalImages; searchProgress?.Report(progress); }); // Download the images using as many threads as configured IAsyncEnumerable <IPhilomenaImage> imagesToDownload = _imageSearch.BeginSearch(cancellationToken, wrappedSearchProgress); await imagesToDownload.ParallelForEachAsync ( async (image) => { _logger.LogDebug("Downloading image {ImageId}", image.Id); // Take a progress slot for this image IProgress <PhilomenaImageDownloadProgressInfo>?imageProgress = null; availableProgress?.TryTake(out imageProgress); // Download the image await _imageDownloader.Download(image, cancellationToken, imageProgress); // Report search download progress lock (searchDownloadProgressLock) { imagesDownloaded++; searchDownloadProgress?.Report(new() { ImagesDownloaded = imagesDownloaded, ImagesTotal = totalImages }); } // Make individual download progress available if one was taken if (imageProgress is not null) { availableProgress !.Add(imageProgress); } }, maxDegreeOfParallelism : _maxDownloadThreads, cancellationToken : cancellationToken ); }
/// <summary> /// When the Step is changed, this method handles the processing of /// the next step /// </summary> protected async void AfterSelectProcessing() { // Disable buttons until processing is complete NextBtn.Enabled = false; PrevBtn.Enabled = false; bool IsErrorFree; // Do processing // Get our previous step switch (pageControl1.SelectedTab.Name) { case "tabPageSelect": // We dont do anything here NextBtn.Enabled = true; break; case "tabPageRedirectType": // We dont do much here PrevBtn.Enabled = NextBtn.Enabled = true; break; case "tabPageVerifyHosts": case "tabPageVerifyIcs": // Create new progress SyncProgress <TaskStep> Myprogress = new SyncProgress <TaskStep>(RedirectStatusUpdate); // Apply redirects IsErrorFree = await Redirector.ApplyRedirectsAsync(Myprogress); if (IsErrorFree) { NextBtn.Enabled = true; } else { // Remove redirect if there are errors await Task.Delay(ERRORPAGE_DELAY); ShowHostsErrorPage(); } break; case "tabPageDiagnostic": // Run in a new thread of course bool DiagnosticResult = await Task.Run <bool>(() => VerifyDnsCache()); // Switch page if (DiagnosticResult) { NextBtn.Enabled = true; } else { // Remove redirect if there are errors Redirector.RemoveRedirects(); await Task.Delay(ERRORPAGE_DELAY); // Show Error Page ShowDnsErrorPage(); } break; case "tabPageSuccess": PrevBtn.Visible = false; CancelBtn.Visible = false; NextBtn.Text = "Finish"; NextBtn.Enabled = true; NextBtn.Location = CancelBtn.Location; return; case "tabPageError": break; } // Unlock the previos button if (pageControl1.SelectedTab != tabPageSelect) { PrevBtn.Enabled = true; } }
private static void ReportProgress(SyncProgress progress) { Console.WriteLine($"{progress.Message} {progress.Elapsed.TotalSeconds.ToString()}"); }
public override async Task Initialize() { await base.Initialize(); await TimeEntriesViewModel.Initialize(); await TimeEntriesLogViewModel.Initialize(); await SuggestionsViewModel.Initialize(); await RatingViewModel.Initialize(); SyncProgressState = dataSource.SyncManager .ProgressObservable.AsDriver(schedulerProvider); var isWelcome = onboardingStorage.IsNewUser; var noTimeEntries = TimeEntriesViewModel.Empty .Select(e => e && SuggestionsViewModel.IsEmpty) .DistinctUntilChanged(); ShouldShowEmptyState = ObservableAddons.CombineLatestAll( isWelcome, noTimeEntries ) .DistinctUntilChanged() .AsDriver(schedulerProvider); ShouldShowWelcomeBack = ObservableAddons.CombineLatestAll( isWelcome.Select(b => !b), noTimeEntries ) .StartWith(false) .DistinctUntilChanged() .AsDriver(schedulerProvider); var connectableTimeEntryIsRunning = dataSource .TimeEntries .CurrentlyRunningTimeEntry .Do(setRunningEntry) .Select(timeEntry => timeEntry != null) .DistinctUntilChanged() .Replay(1); connectableTimeEntryIsRunning.Connect(); IsTimeEntryRunning = connectableTimeEntryIsRunning.AsDriver(schedulerProvider); CurrentTimeEntryHasDescription = dataSource .TimeEntries .CurrentlyRunningTimeEntry .Select(te => !string.IsNullOrWhiteSpace(te?.Description)) .DistinctUntilChanged() .AsDriver(schedulerProvider); timeService .CurrentDateTimeObservable .Where(_ => currentTimeEntryStart != null) .Subscribe(currentTime => CurrentTimeEntryElapsedTime = currentTime - currentTimeEntryStart.Value) .DisposedBy(disposeBag); dataSource .SyncManager .ProgressObservable .Subscribe(progress => SyncingProgress = progress) .DisposedBy(disposeBag); interactorFactory .GetItemsThatFailedToSync() .Execute() .Select(i => i.Count()) .Subscribe(n => NumberOfSyncFailures = n) .DisposedBy(disposeBag); timeService.MidnightObservable .Subscribe(onMidnight) .DisposedBy(disposeBag); switch (urlNavigationAction) { case ApplicationUrls.Main.Action.Continue: await continueMostRecentEntry(); break; case ApplicationUrls.Main.Action.Stop: await stopTimeEntry(); break; } ratingViewExperiment .RatingViewShouldBeVisible .Subscribe(presentRatingViewIfNeeded) .DisposedBy(disposeBag); onboardingStorage.StopButtonWasTappedBefore .Subscribe(hasBeen => hasStopButtonEverBeenUsed = hasBeen) .DisposedBy(disposeBag); }
private void UpdateProgress(SyncProgress obj) { tslStatus.Text = obj.Message; }
public Task SendTitleEnumerationProgress(SyncProgress syncProgress) { return(_hub.Clients.All.SendAsync("OnSyncProgress", syncProgress)); }
private void updateSyncingIndicator(SyncProgress state) { refreshLayout.Refreshing = state == Syncing; }
/// <summary> /// Event fired when the Launch Battlefield 2 button is pushed on the Launcher Tab /// </summary> private async void LaunchButton_Click(object sender, EventArgs args) { // Lock button to prevent spam LaunchButton.Enabled = false; // Close the app if (BF2Client.IsRunning) { BF2Client.Stop(); return; } // Show overlay first, which provides the smokey (Modal) background using (ModalOverlay overlay = new ModalOverlay(this, 0.3)) { // Show overlay overlay.Show(this); // Make sure a mod is selected if (ModComboBox.SelectedIndex < 1) { MetroMessageBox.Show(overlay, "Please select a Bf2 Mod before attempting to start the game!", "No Mod Selected", MessageBoxButtons.OK, MessageBoxIcon.Asterisk, 150 ); overlay.Close(); // Reset button BF2Client_Exited(); // Focus the mod select ModComboBox.Focus(); return; } // Grab our mod and provider BF2Mod Mod = ModComboBox.SelectedItem as BF2Mod; ServiceProvider Provider = ProviderComboBox.SelectedItem as ServiceProvider; Server Server = ServerComboBox.SelectedItem as Server; // Remove old redirects Redirector.RemoveRedirects(); // If we arent using a provider, skip to just launching the game if (Provider == null) { goto StartClient; } // Apply redirects in a new thread SyncProgress <TaskStep> MyProgress = new SyncProgress <TaskStep>(RedirectStatusUpdate); bool Success = await Redirector.ApplyRedirectsAsync(Provider, MyProgress); if (!Success) { // Show error MetroMessageBox.Show(overlay, ErrorStep.Description, "Redirect Error", MessageBoxButtons.OK, MessageBoxIcon.Error, 180); overlay.Close(); // Reset button BF2Client_Exited(); return; } // Show the Task Form TaskForm.Show(this, "Launching Battlefield 2", $"Starting Battlefield 2 with mod \"{Mod.Title}\"", false, ProgressBarStyle.Marquee, 0); // Our goto to start the game StartClient: { try { // === // ALWAYS Remove all temporary keys before this next point // === Params.Reload(LaunchParamsTextBox.Text); Params.ClearTempParams(); // If we are auto joining a server, we must login! if (Provider != null && (Server != null || CredentialsCheckBox.Checked)) { // Prompt user to login! using (LoginForm f = new LoginForm(Provider)) { DialogResult Res = f.ShowDialog(overlay); if (Res == DialogResult.Cancel) { // Reset button TaskForm.CloseForm(); BF2Client_Exited(); return; } // Set server params if (Server != null) { Params.AddOrSet("joinServer", Server.Address); Params.AddOrSet("port", Server.Port.ToString()); } // Set login params Params.AddOrSet("playerName", f.UsernameTextBox.Text); Params.AddOrSet("playerPassword", f.PasswordTextBox.Text); } } // Start the client executable BF2Client.Start(Mod, Params.BuildString(true)); } catch (Exception e) { // Show error MetroMessageBox.Show(overlay, e.Message, "Failure to Launch", MessageBoxButtons.OK, MessageBoxIcon.Error, 180); BF2Client_Exited(); } } // Close the task form TaskForm.CloseForm(); // Close Task form and overlay using (RunningOverlay = new GameRunningForm(this)) { RunningOverlay.ShowDialog(overlay); } // Close Overlay overlay.Close(); LaunchButton.Focus(); } }
private void DispatchSyncProgress(long bytesLoaded, long bytesTotal, int status, string callbackId, bool keepCallback = true) { //Debug.WriteLine("DispatchSyncProgress : " + callbackId); // send a progress change event SyncProgress progEvent = new SyncProgress(bytesTotal); progEvent.BytesLoaded = bytesLoaded; int percent = (int)((bytesLoaded / (double)bytesTotal) * 100); // jump from 50 to 100 once unzip is done if(bytesLoaded != bytesTotal && status != 3){ percent = percent / 2; } string result = "{\"progress\":" + percent + ", \"status\":" + status + "}"; PluginResult plugRes = new PluginResult(PluginResult.Status.OK, result); plugRes.KeepCallback = keepCallback; plugRes.CallbackId = callbackId; DispatchCommandResult(plugRes, callbackId); }
/// <summary> /// When the Step is changed, this method handles the processing of /// the next step /// </summary> protected async void AfterSelectProcessing() { // Disable buttons until processing is complete NextBtn.Enabled = false; PrevBtn.Enabled = false; bool IsErrorFree; // Do processing // Get our previous step switch (pageControl1.SelectedTab.Name) { case "tabPageSelect": // We dont do anything here NextBtn.Enabled = true; break; case "tabPageRedirectType": // We dont do much here PrevBtn.Enabled = NextBtn.Enabled = true; break; case "tabPageVerifyHosts": case "tabPageVerifyIcs": // Create new progress SyncProgress<TaskStep> Myprogress = new SyncProgress<TaskStep>(RedirectStatusUpdate); // Apply redirects IsErrorFree = await Redirector.ApplyRedirectsAsync(Myprogress); if (IsErrorFree) { NextBtn.Enabled = true; } else { // Remove redirect if there are errors await Task.Delay(ERRORPAGE_DELAY); ShowHostsErrorPage(); } break; case "tabPageDiagnostic": // Run in a new thread of course bool DiagnosticResult = await Task.Run<bool>(() => VerifyDnsCache()); // Switch page if (DiagnosticResult) { NextBtn.Enabled = true; } else { // Remove redirect if there are errors Redirector.RemoveRedirects(); await Task.Delay(ERRORPAGE_DELAY); // Show Error Page ShowDnsErrorPage(); } break; case "tabPageSuccess": PrevBtn.Visible = false; CancelBtn.Visible = false; NextBtn.Text = "Finish"; NextBtn.Enabled = true; NextBtn.Location = CancelBtn.Location; return; case "tabPageError": break; } // Unlock the previos button if (pageControl1.SelectedTab != tabPageSelect) PrevBtn.Enabled = true; }