WPF Backgroundworker dowork work completed progress changed
<Window x:Class="WpfApp178.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp178" mc:Ignorable="d" WindowState="Maximized" Title="MainWindow" Height="450" Width="800"> <Grid TextBlock.FontSize="16"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <StackPanel Orientation="Horizontal" Margin="6"> <TextBlock Text="From:"/> <TextBox Margin="10,2,2,2" x:Name="_from"/> <TextBlock Text="To:" Margin="20,0,0,0"/> <TextBox Margin="10,2,2,2" Width="120" MaxLength="10" x:Name="_to"/> </StackPanel> <StackPanel Orientation="Horizontal" Grid.Row="1" Margin="6"> <Button Content="Calculate" Padding="4" x:Name="calc" Click="Button_Click"/> <Button Content="Cancel" Padding="4" x:Name="cancel" Click="cancel_Click"/> </StackPanel> <ProgressBar x:Name="progress" Grid.Row="2" Height="30" Margin="4"/> <TextBlock x:Name="_result" Grid.Row="3" FontSize="20" Margin="6" HorizontalAlignment="Center" /> <TextBlock x:Name="progressTb" Grid.Row="4" FontSize="20" Margin="6" HorizontalAlignment="Center"/> </Grid> </Window> using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Data.SqlTypes; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WpfApp178 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { ObservableCollection<int> numbers = new ObservableCollection<int>(); object lockObj = new object(); CancellationTokenSource cts; BackgroundWorker worker; public MainWindow() { InitializeComponent(); } static int CountPrimes(int from,int to,CancellationToken ct) { int total = 0; for(int i=from;i<=to;i++) { if(ct.IsCancellationRequested) { return -1; } bool isPrime = true; int limit = (int)Math.Sqrt(i); for(int j=2;j<=limit;j++) { if(i%j==0) { isPrime = false; break; } } if (isPrime) { total++; } } return total; } private void Button_Click(object sender, RoutedEventArgs e) { worker = new BackgroundWorker(); worker.WorkerSupportsCancellation = true; worker.WorkerReportsProgress = true; worker.ProgressChanged += Worker_ProgressChanged; worker.DoWork += Worker_DoWork; worker.RunWorkerCompleted += Worker_RunWorkerCompleted; calc.IsEnabled = false; cancel.IsEnabled = true; _result.Text = "Calculating..."; var data = new PrimeInputData { First = int.Parse(_from.Text), Last = int.Parse(_to.Text) }; worker.RunWorkerAsync(data); } private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e) { progress.Value = e.ProgressPercentage; _result.Text = $"Calculating:{progress.Value}%"; progressTb.Text = progress.Value.ToString(); } private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { _result.Text = e.Cancelled ? "Operation Cancelled" : $"Total Primes:{e.Result}"; calc.IsEnabled = true; cancel.IsEnabled = false; } private void Worker_DoWork(object sender, DoWorkEventArgs e) { var data = e.Argument as PrimeInputData; int count = 0; bool isFirstZero = true; worker.ReportProgress(0); int range = data.Last - data.First + 1, progressCount = 0; for(int i=data.First;i<=data.Last;i++) { if(worker.CancellationPending) { e.Cancel = true; break; } int limit = (int)Math.Sqrt(i); bool isPrime = true; for(int j=2;j<=limit;j++) { if(i%j==0) { isPrime = false; break; } } if(isPrime) { count++; } if(++progressCount%100==0) { int value = progressCount * 100 / range; if(value>0) { worker.ReportProgress(value); } } } if(!e.Cancel) { worker.ReportProgress(100); e.Result = count; } } private void cancel_Click(object sender, RoutedEventArgs e) { worker.CancelAsync(); } } class PrimeInputData { public int First { get; set; } public int Last { get; set; } } }