MainWindow.xaml.cs
public partial class MainWindow : Window { //CancellationTokenSource用于创建可分配给不同任务的CancellationToken对象。任何持有CancellationTokenSource的对象都可以调用其Cancel方法,从而 //将CancellationToken的IsCancellationRequested设置为true CancellationTokenSource cts; //CancellationToken包含一个任务是否应该被取消的消息,拥有CancellationToken的对象会定期检查其持有的token状态,如果CancellationToken的 //IsCancellationRequested属性为true,就会取消任务执行。 CancellationToken ct; public MainWindow() { InitializeComponent(); } private async void btnProcess_Click(object sender, RoutedEventArgs e) { btnProcess.IsEnabled = false; cts = new CancellationTokenSource(); //为ct分发token ct = cts.Token; int completedPercent = 0; for(int i=0;i<10;i++) { //如果ct.IsCancellationRequested==true,那么任务会被取消 if (ct.IsCancellationRequested) break; try { //Task.Delay不会阻塞线程,也就是执行到这里时,异步等待0.5s,但控制权会交还给消息泵执行下一个动作 await Task.Delay(500, ct); completedPercent = (i + 1) * 10; } catch(TaskCanceledException ex) { completedPercent = i * 10; } processBar.Value = completedPercent; } string message = ct.IsCancellationRequested ? string.Format("Process was cancelled at {0}%.", completedPercent) : "Process completed normally"; MessageBox.Show(message, "Completion Status"); processBar.Value = 0; btnProcess.IsEnabled = true; btnCancel.IsEnabled = true; } private void btnCancel_Click(object sender, RoutedEventArgs e) { if(!btnProcess.IsEnabled) { btnCancel.IsEnabled = false; cts.Cancel(); } } }
MainWindows.xaml
<StackPanel> <Button Name="btnProcess" Width="100" Click="btnProcess_Click" HorizontalAlignment="Right" Margin="10,15,10,10">Process</Button> <Button Name="btnCancel" Width="100" Click="btnCancel_Click" HorizontalAlignment="Right" Margin="10,0">Cancel</Button> <ProgressBar Name="processBar" Height="20" Width="500" Margin="10" HorizontalAlignment="Right"></ProgressBar> </StackPanel>