Wpf BackgroundWorker WorkerSupportsCancellation CancellationPending
//xaml <Window x:Class="WpfApp37.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:WpfApp37" WindowState="Maximized" mc:Ignorable="d" 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"/> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal" Margin="6"> <TextBlock Text="From:"/> <TextBox Margin="10,2,2,2" Width="120" MaxLength="10" 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 Grid.Row="1" Orientation="Horizontal" Margin="6"> <Button Content="Calculate" x:Name="_calcBtn" Padding="4" Click="calc_Click" /> <Button Content="Cancel" x:Name="_cancelBtn" Padding="4" Click="_cancelBtn_Click"/> </StackPanel> <ProgressBar x:Name="_progressBar" Grid.Row="2" Height="30" Margin="4"/> <TextBlock Grid.Row="3" x:Name="_result" FontSize="20" Margin="6" HorizontalAlignment="Center"/> </Grid> </Window> //cs using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Linq.Expressions; 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 WpfApp37 { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { BackgroundWorker _bgWorker; int _cnt = 0; public MainWindow() { InitializeComponent(); } private void calc_Click(object sender, RoutedEventArgs e) { _bgWorker = new BackgroundWorker(); _bgWorker.WorkerSupportsCancellation = true; _bgWorker.DoWork += _bgWorker_DoWork; _bgWorker.RunWorkerCompleted += _bgWorker_RunWorkerCompleted; _calcBtn.IsEnabled = false; _cancelBtn.IsEnabled = true; _result.Text = "Calculating..."; var data = new PrimeInputData() { First = int.Parse(_from.Text), Last = int.Parse(_to.Text) }; _bgWorker.RunWorkerAsync(data); } private void _bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (e.Cancelled) { _result.Text = $"Cancelled Primes:{_cnt}"; } else { _result.Text = $"Total Primes:{e.Result}"; } _calcBtn.IsEnabled = true; _cancelBtn.IsEnabled = false; } private void _bgWorker_DoWork(object sender, DoWorkEventArgs e) { var data = e.Argument as PrimeInputData; if (data != null) { for (int i = data.First; i <= data.Last; i++) { if (_bgWorker.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) { _cnt++; } } e.Result = _cnt; } } private void _cancelBtn_Click(object sender, RoutedEventArgs e) { _bgWorker.CancelAsync(); _calcBtn.IsEnabled = true; _cancelBtn.IsEnabled = false; } } class PrimeInputData { public int First { get; set; } public int Last { get; set; } } }