简单多线程BackgroundWorker

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了简单多线程BackgroundWorker相关的知识,希望对你有一定的参考价值。

技术分享

 

BackgroundWorker是·net里用来执行多线程任务的控件,它允许编程者在一个单独的线程上执行一些操作。
在开发多线程程序时,有些时候仅仅只是想实现一个简单的多线程,并不需要写一大堆的委托、回调等等,那么BackgroundWorker便是最好的选择。
本Demo演示BackgroundWorker在WPF中的简单线程例子!

---------------------------------------------------------------------XAML代码-----------------------------------------------------------

<Window x:Class="LshBackgroundWorkerDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="BackgroundWorkerDemo" Width="800" Height="270"  Loaded="Window_Loaded">
    <ScrollViewer  VerticalScrollBarVisibility="Auto">
    <StackPanel>
        
        <WrapPanel>
            <Button Name="btnStartThread"  Content="启动线程" Click="btnStartThread_Click"/>
            <Button Name="btnPauseThread"  Content="暂停线程" Click="btnPauseThread_Click"/>
            <Button Name="btnContinueThread" Content="恢复线程" Click="btnContinueThread_Click"/>
            <Button Name="btnTerminationThread"  Content="终止线程" Click="btnTerminationThread_Click"/>
        </WrapPanel>
        <WrapPanel  HorizontalAlignment="Center">
            <TextBlock Text="数量:" Style="{StaticResource txtBlockSyle}">

            </TextBlock>
            <TextBox Name="txtNum" Style="{StaticResource txtNum}"></TextBox>
        </WrapPanel>
        <GroupBox Header="线程状态显示" Margin="10">
            <Grid>
                <ProgressBar x:Name="progressBar" Height="50"/>
                <WrapPanel HorizontalAlignment="Center">
                    <TextBlock Text="   已加载:"  Style="{StaticResource txtBlockSyle}" />
                    <TextBlock x:Name="txtBlockNum" Text="0%"  Style="{StaticResource txtBlockSyle}"/>
                </WrapPanel>
            </Grid>
        </GroupBox>
    </StackPanel>
    </ScrollViewer>
</Window>

  

 ---------------------------------------------------------------------Style代码-----------------------------------------------------------

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="Button">
        <Setter Property="FontSize" Value="20"></Setter>
        <Setter Property="Margin" Value="20" ></Setter>
        <Setter Property="Padding" Value="10 5 10 5"></Setter>
        <Setter Property="Width" Value="150"></Setter>
        <Setter Property="Background" Value="Black"></Setter>  
        <Setter Property="FontWeight" Value="Bold"></Setter>
        <Setter Property="Effect">
            <Setter.Value>
                <DropShadowEffect Color="{DynamicResource {x:Static SystemColors.DesktopColorKey}}"/>
            </Setter.Value>
        </Setter>
        <Setter Property="Foreground">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
                <GradientStop Color="#FFEEF906" Offset="1"/>
                <GradientStop Color="#FFDA9D86"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="TextBox" x:Key="txtNum">
        <Setter Property="Width" Value="150"></Setter>
        <Setter Property="Height" Value="35"></Setter>
        <Setter Property="Text" Value="10000"></Setter>
        <Setter Property="FontSize" Value="20"></Setter>
    </Style>
    <Style TargetType="TextBlock" x:Key="txtBlockSyle">
        <Setter Property="Width" Value="100"></Setter>
        <Setter Property="Height" Value="40"></Setter>
        <Setter Property="FontSize" Value="20"></Setter>
        <Setter Property="Padding" Value="0 5 0 0"></Setter>
        <Setter Property="Margin" Value="0 5 0 0"></Setter>
    </Style>
</ResourceDictionary>

  

---------------------------------------------------------------------CS代码-----------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
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;
using System.Text.RegularExpressions;
using System.Threading;

namespace LshBackgroundWorkerDemo
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        #region 公共变量

        //简单线程对象
        private BackgroundWorker backgroundWorker;
        //指定的操作数量
        private int number;
        //用该对象控制线程的暂停和继续
        private ManualResetEvent manualReset = new ManualResetEvent(true);

        #endregion

        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 启动线程单击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnStartThread_Click(object sender, RoutedEventArgs e)
        {
            //验证用户输入是否正确
            if (vili()) 
            {
                //初始化所有控件以及数据
                int num = int.Parse(txtNum.Text);
                number = num;
                progressBar.Maximum = num;
                progressBar.Minimum = 0;
                //启动线程
                backgroundWorker.RunWorkerAsync(num);
            }
            
          
        }
        /// <summary>
        /// 线程执行函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            
            for (int i = 0; i <= Convert.ToInt32(e.Argument); i++)
            {
                //判断用户是否已经取消该线程执行,如果没有则正常执行
                if (!backgroundWorker.CancellationPending)
                {
                    backgroundWorker.ReportProgress(i);
                    //等待消息通知,为true则不进行阻塞,false则进行阻塞暂停该线程执行
                    manualReset.WaitOne();
                    Thread.Sleep(1);
                    
                }

            }
            
        }

        /// <summary>
        /// 线程结束回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
           global::System.Windows.MessageBox.Show("结束"); 
            
        }

        /// <summary>
        /// 线程操作数被修改回调函数
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            double baifen = ((double)e.ProgressPercentage / (double)number) * 100;
            txtBlockNum.Text = baifen + "%";
            progressBar.Value = e.ProgressPercentage;
        }

        /// <summary>
        /// 验证文本框
        /// </summary>
        private bool vili() 
        {
            string inputTxt = this.txtNum.Text;
            Regex gex = new Regex(@"^-?\d+\.?\d*$");
            if (!gex.IsMatch(inputTxt)) 
            {
                global::System.Windows.MessageBox.Show("文本框内容必须是纯数字!");
                return false;
            }
            return true;
        }

        /// <summary>
        /// 暂停线程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnPauseThread_Click(object sender, RoutedEventArgs e)
        {
            manualReset.Reset();
        }

        /// <summary>
        /// 窗体加载完成时执行事件绑定
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            backgroundWorker = new BackgroundWorker();
            backgroundWorker.WorkerReportsProgress = true;
            backgroundWorker.WorkerSupportsCancellation = true;
            backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);
            backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(backgroundWorker_ProgressChanged);
            backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(backgroundWorker_RunWorkerCompleted);
        }

        /// <summary>
        /// 恢复线程运行
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnContinueThread_Click(object sender, RoutedEventArgs e)
        {
            manualReset.Set();
        }

        /// <summary>
        /// 结束线程
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnTerminationThread_Click(object sender, RoutedEventArgs e)
        {
            backgroundWorker.CancelAsync();
            this.Dispatcher.Invoke(new Action(() =>
            {
                progressBar.Value = 0;
                txtBlockNum.Text = "0%";
            }));
           
        }
       
    }
}

  

Demo下载地址:http://yunpan.cn/cfWBaYYrd3wGu
提取码 7172
技术分享

以上是关于简单多线程BackgroundWorker的主要内容,如果未能解决你的问题,请参考以下文章

C# backgroundworker使用方法

多线程更新UI的常用方法

两个同时运行的线程控件(BackgroundWorker)串数据

线程封装组件(BackgroundWorker)和线程(Thread)

C#中 BackGroundWorker与Thread的区别?

C#如何在BackgroundWorker 后台线程中使用定时器?