WPF使用BackgroundWorker进行单独线程操作

之前使用线程池来进行异步计算,示例如下所示:
WPF从非UI线程中更新UI元素
WPF取消一个线程的执行


此文章还使用了BackgroundWorker 中的进度条事件,效果如下所示:
在这里插入图片描述
点击取消按钮后,效果如下所示:
在这里插入图片描述


XAML布局如下所示:

<StackPanel>
        <StackPanel Orientation="Horizontal">
            <Border
                Margin="10"
                BorderBrush="Black"
                BorderThickness="1">
                <TextBlock Margin="10" Text="开始数字:1" />
            </Border>
            <Border
                Margin="10"
                BorderBrush="Black"
                BorderThickness="1">
                <TextBlock Margin="10" Text="结束数字:1000000000" />
            </Border>
        </StackPanel>
        <StackPanel>
            <Border
                Margin="10"
                BorderBrush="Black"
                BorderThickness="1">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Margin="10" Text="奇数个数:" />
                    <TextBox
                        x:Name="jsValue"
                        Width="Auto"
                        Height="20"
                        Text="0" />
                </StackPanel>
            </Border>
            <Border
                Margin="10"
                BorderBrush="Black"
                BorderThickness="1">
                <StackPanel Orientation="Horizontal">
                    <TextBlock Margin="10" Text="偶数个数:" />
                    <TextBox
                        x:Name="esValue"
                        Width="Auto"
                        Height="20"
                        Text="0" />
                </StackPanel>
            </Border>
        </StackPanel>

        <ProgressBar
            x:Name="progressBar"
            Height="30"
            Margin="10" />

        <StackPanel>
            <Button
                x:Name="btn"
                Width="120"
                Height="30"
                Margin="20"
                Click="Button_Click"
                Content="开始计算" />
            <Button
                Width="120"
                Height="30"
                Margin="20"
                Click="Button_Click1"
                Content="取消计算" />
        </StackPanel>
</StackPanel>

隐藏代码如下所示:

using System;
using System.ComponentModel;
using System.Windows;

namespace TheadPoolDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Calculator(int from, int to)
        {
            tmpJsValue = 0;
            tmpEsValue = 0;

            Int32 interation = (to - from) / 100;   // 间隔多少
            for (Int32 i = from; i < to; i++)
            {
                // 判断是否请求取消
                if (worker.CancellationPending)
                {
                    return;
                }

                if (i % 2 == 0) ++tmpEsValue;
                else ++tmpJsValue;


                if ((i % interation == 0) && (worker != null) && (worker.WorkerReportsProgress == true))
                {
                    worker.ReportProgress(i / interation);
                }

            }
        }

        Int32 tmpJsValue = 0;
        Int32 tmpEsValue = 0;

        BackgroundWorker worker = null;

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            this.btn.IsEnabled = false;

            this.esValue.Text = "0";
            this.jsValue.Text = "0";

            worker = new BackgroundWorker();
            worker.WorkerSupportsCancellation = true;                       // 支持异步取消操作
            worker.WorkerReportsProgress = true;                            // 允许报告进度更新事件
            worker.ProgressChanged += Worker_ProgressChanged;               // 调用 reportprogress 时发生
            worker.DoWork += Worker_DoWork;                                 // 需要做的事情
            worker.RunWorkerCompleted += Worker_RunWorkerCompleted;         // 操作完成之后需要干的事情
            worker.RunWorkerAsync(new Tuple<Int32, Int32>(1, 1000000000));  // 开始操作,调用 DoWork
        }

        private void Worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.progressBar.Value = e.ProgressPercentage;      // 传入的值
        }

        private void Worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // 操作完成之后,注销事件,并且显示数据
            if (sender is BackgroundWorker worker)
            {
                // 判断是否已经取消操作成功了
                if (e.Cancelled == true)
                {
                    this.jsValue.Text = "取消成功!";
                    this.esValue.Text = "取消成功!";
                }
                else
                {
                    this.jsValue.Text = tmpJsValue.ToString();
                    this.esValue.Text = tmpEsValue.ToString();
                }

                worker.DoWork -= Worker_DoWork;
                worker.RunWorkerCompleted -= Worker_RunWorkerCompleted;
                worker = null;
            }

            this.btn.IsEnabled = true;
            this.progressBar.Value = 0;
        }

        private void Worker_DoWork(object sender, DoWorkEventArgs e)
        {
            // 需要做的事情:计算奇偶数
            var args = (Tuple<Int32, Int32>)e.Argument;
            Calculator(args.Item1, args.Item2);

            if (worker.CancellationPending) // 判断是否请求取消
            {
                e.Cancel = true;            // 取消该事件        响应上面的操作
            }
        }



        private void Button_Click1(object sender, RoutedEventArgs e)
        {
            worker.CancelAsync();       // 请求取消
        }
    }
}
©️2020 CSDN 皮肤主题: 终极编程指南 设计师:CSDN官方博客 返回首页