C#多线程之BackgroundWorker

一、BackgroundWorker介绍

我们有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应。解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作。新建线程可以用 Thread 类实现多线程同时操作。简单的方法可以通过 BackgroundWorker 类实现。BackgroundWorker是·net里用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。

  常用方法

  1.RunWorkerAsync 开始执行后台操作。引发 DoWork 事件

  2.CancelAsync 请求取消挂起的后台操作。

  注意:这个方法是将 CancellationPending 属性设置为 true,并不会终止后台操作。在后台操作中要检查

CancellationPending 属性,来决定是否要继续执行耗时的操作。

  3.ReportProgress引发 ProgressChanged 事件。

  常用属性

  1.CancellationPending 指示应用程序是否已请求取消后台操作。只读属性,默认为 false,当执行了 CancelAsync 方法后,值为 true。

  2.WorkerSupportsCancellation指示是否支持异步取消。要执行 CancelAsync 方法,需要先设置该属性为 true。

  3.WorkerReportsProgress指示是否能报告进度。要执行 ReportProgress 方法,需要先设置该属性为 true。

  常用事件

  1.DoWork 调用 RunWorkerAsync 方法时发生。

  2.RunWorkerCompleted后台操作已完成、被取消或引发异常时发生。

  3.ProgressChanged调用 ReportProgress 方法时发生。

二、实例

点击开始,出现动画,并计数。

xml

<Window x:Class="测试大数据的图表.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:测试大数据的图表"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid Name="grid1">
        <Button Content="开始" Height="23" HorizontalAlignment="Left" Margin="41,20,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
        <Button Content="stop" Margin="165,18,543,377"  Click="Button_Click"/>
        <DataGrid AutoGenerateColumns="False" Height="99" HorizontalAlignment="Left" Margin="40,70,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="441" />
        <Canvas Name="loading" RenderTransformOrigin="0.5,0.5" Visibility="Collapsed" HorizontalAlignment="Center" VerticalAlignment="Center" Width="120" Height="120" Margin="187,76,241,85">
            <Ellipse Width="15" Height="15" Canvas.Left="55" Canvas.Top="31" Stretch="Fill" Fill="#FFD1D1F7" Opacity="1.0"/>
            <Ellipse Width="15" Height="15" Canvas.Left="38" Canvas.Top="39" Stretch="Fill" Fill="Blue" Opacity="0.8"/>
            <Ellipse Width="15" Height="15" Canvas.Left="36" Canvas.Top="58" Stretch="Fill" Fill="#FF0000FE" Opacity="0.7"/>
            <Ellipse Width="15" Height="15" Canvas.Left="52" Canvas.Top="67" Stretch="Fill" Fill="Blue" Opacity="0.6"/>
            <Ellipse Width="15" Height="15" Canvas.Left="68" Canvas.Top="61" Stretch="Fill" Fill="#FF2E2EFF" Opacity="0.5"/>
            <Ellipse Width="15" Height="15" Canvas.Left="69" Canvas.Top="42" Stretch="Fill" Fill="#FF6F6FFF" Opacity="0.4"/>
            <Canvas.RenderTransform>
                <RotateTransform x:Name="SpinnerRotate" Angle="0" />
            </Canvas.RenderTransform>
            <Canvas.Triggers>
                <EventTrigger RoutedEvent="ContentControl.Loaded">
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetName="SpinnerRotate" Storyboard.TargetProperty="(RotateTransform.Angle)" From="0" To="360" Duration="0:0:0.8" RepeatBehavior="Forever" />
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Canvas.Triggers>
        </Canvas>
        <Label Name="lab_pro" Content="Label" Height="28" Margin="140,14,315,239" />
    </Grid>
</Window>

C#

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

namespace 测试大数据的图表
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
          
        }

        BackgroundWorker bgMeet = new BackgroundWorker();

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            if (bgMeet.IsBusy) // 防止重复执行异步操作引发错误
                return;
            bgMeet.WorkerReportsProgress = true;//报告完成进度  
            bgMeet.WorkerSupportsCancellation = true;//允许用户终止后台线程 
            bgMeet.DoWork += new DoWorkEventHandler(bgMeet_DoWork);
            bgMeet.ProgressChanged += new ProgressChangedEventHandler(bgMeet_ProgressChanged);
            bgMeet.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgMeet_RunWorkerCompleted);

            bgMeet.RunWorkerAsync();
        }

        /// <summary>
        /// 异步操作完成或中途终止会触发该事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bgMeet_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            loading.Visibility = System.Windows.Visibility.Collapsed;
            this.Dispatcher.Invoke(new Action(() =>
            {
                this.lab_pro.Content = "完成";
            }));
        }


        /// <summary>
        /// 提供一个在 0 到 100 之间的整数,它表示后台活动已完成的百分比
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bgMeet_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            this.Dispatcher.Invoke(new Action(() =>
            {
                this.lab_pro.Content = e.ProgressPercentage;
            }));
        }

        /// <summary>
        /// 开始异步操作执行该方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void bgMeet_DoWork(object sender, DoWorkEventArgs e)
        {
            this.Dispatcher.Invoke(new Action(() =>
            {
                loading.Visibility = System.Windows.Visibility.Visible;
            }));


            for (int i = 0; i < 505; i++)
            {
                if (bgMeet.CancellationPending)
                {
                    e.Cancel = true;
                    return;
                }
                bgMeet.ReportProgress(i);
                System.Threading.Thread.Sleep(100);
            }

        }
       

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (bgMeet != null && bgMeet.WorkerSupportsCancellation == true)
            {
                loading.Visibility = System.Windows.Visibility.Hidden; ;
                bgMeet.CancelAsync();//取消后台操作  
                bgMeet.Dispose();//释放资源  
            }
        }
    }

}

 

参考:

https://www.cnblogs.com/javier520/p/10842161.html

https://www.cnblogs.com/zhaoshujie/p/9634136.html

https://blog.csdn.net/qq_33222460/article/details/79946847

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值