首页 > 代码库 > D31_02_BackgroundWorker类

D31_02_BackgroundWorker类

imageimage

 

 

 

 

 

 

 

 

 

 

 

 

<Window x:Class="demo.MainWindow"        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        Title="MainWindow" Height="323.2" Width="305.6"        xmlns:cm="clr-namespace:System.ComponentModel;assembly=System">    <Window.Resources>        <!--          DoWork:        -->        <cm:BackgroundWorker x:Key="backgroundWorker"                             DoWork="backgroundWorker_DoWork"                             RunWorkerCompleted="backgroundWorker_RunWorkerCompleted"                             WorkerReportsProgress="True"                             ProgressChanged="backgroundWorker_ProgressChanged"                             WorkerSupportsCancellation="True" ></cm:BackgroundWorker>    </Window.Resources>    <Grid Margin="5">        <Grid.RowDefinitions>            <RowDefinition Height="Auto"></RowDefinition>            <RowDefinition Height="Auto"></RowDefinition>            <RowDefinition Height="Auto"></RowDefinition>            <RowDefinition></RowDefinition>            <RowDefinition Height="Auto"></RowDefinition>        </Grid.RowDefinitions>        <Grid.ColumnDefinitions>            <ColumnDefinition Width="Auto"></ColumnDefinition>            <ColumnDefinition></ColumnDefinition>        </Grid.ColumnDefinitions>        <TextBlock Margin="5">Frome:</TextBlock>        <TextBox Name="txtFrom" Grid.Column="1" Margin="5">1</TextBox>        <TextBlock Grid.Row="1" Margin="5">To:</TextBlock>        <TextBox Name="txtTo" Grid.Row="1" Grid.Column="1" Margin="5">500000</TextBox>                <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="1">            <Button Name="cmdFind" Margin="5" Padding="3"  Click="cmdFind_Click">Find Primes</Button>            <Button Name="cmdCancel" Margin="5" Padding="3" Click="cmdCancel_Click">Cancel</Button>        </StackPanel>                <TextBlock Grid.Row="3" Margin="5">Results:</TextBlock>        <ListBox Name="lstPrimes" Grid.Row="3" Grid.Column="1" Margin="5"></ListBox>                <ProgressBar Name="progressBar" Grid.Row="4" Grid.ColumnSpan="2"                     Margin="5" VerticalAlignment="Bottom" MinHeight="20"                     Minimum="0" Maximum="100" Height="20"></ProgressBar>    </Grid></Window>

 

 

using System;using System.Collections.Generic;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.ComponentModel;namespace demo{    /// <summary>    /// MainWindow.xaml 的交互逻辑    /// </summary>    public partial class MainWindow : Window    {        private BackgroundWorker backgroundWorker;        public MainWindow()        {            InitializeComponent();            backgroundWorker = ((BackgroundWorker)this.FindResource("backgroundWorker"));        }        private void cmdFind_Click(object sender, RoutedEventArgs e)        {            // Disable the button and clear previous results.            cmdFind.IsEnabled = false;            cmdCancel.IsEnabled = true;            lstPrimes.Items.Clear();            // Get the search range.            int from, to;            if (!Int32.TryParse(txtFrom.Text, out from))            {                MessageBox.Show("Invalid From value.");                return;            }            if (!Int32.TryParse(txtTo.Text, out to))            {                MessageBox.Show("Invalid To value.");                return;            }            // Start the search for primes on another thread.            FindPrimesInput input = new FindPrimesInput(from, to);            backgroundWorker.RunWorkerAsync(input);        }        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)        {            // Get the input values.            FindPrimesInput input = (FindPrimesInput)e.Argument;            // Start the search for primes and wait.            int[] primes = Worker.FindPrimes(input.From, input.To, backgroundWorker);            if (backgroundWorker.CancellationPending)            {                e.Cancel = true;                return;            }            // Return the result.            e.Result = primes;        }        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)        {            if (e.Cancelled)            {                MessageBox.Show("Search cancelled.");            }            else if (e.Error != null)            {                // An error was thrown by the DoWork event handler.                MessageBox.Show(e.Error.Message, "An Error Occurred");            }            else            {                int[] primes = (int[])e.Result;                foreach (int prime in primes)                {                    lstPrimes.Items.Add(prime);                }            }            cmdFind.IsEnabled = true;            cmdCancel.IsEnabled = false;            progressBar.Value = 0;        }        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)        {            progressBar.Value = e.ProgressPercentage;        }        private void cmdCancel_Click(object sender, RoutedEventArgs e)        {            backgroundWorker.CancelAsync();        }    }}

 

FindPrimesInput .cs

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace demo{    class FindPrimesInput    {        public int To        {            get;            set;        }        public int From        {            get;            set;        }        public FindPrimesInput(int from, int to)        {            To = to;            From = from;        }    }}

 

Worker.cs

#region Using directivesusing System;using System.Collections.Generic;using System.Text;#endregionnamespace demo{    public class Worker    {        public static int[] FindPrimes(int fromNumber, int toNumber)        {            return FindPrimes(fromNumber, toNumber, null);        }        public static int[] FindPrimes(int fromNumber, int toNumber, System.ComponentModel.BackgroundWorker backgroundWorker)        {            int[] list = new int[toNumber - fromNumber];            // Create an array containing all integers between the two specified numbers.            for (int i = 0; i < list.Length; i++)            {                list[i] = fromNumber;                fromNumber += 1;            }            //find out the module for each item in list, divided by each d, where            //d is < or == to sqrt(to)            //if the remainder is 0, the nubmer is a composite, and thus            //we mark its position with 0 in the marks array,            //otherwise the number is a prime, and thus mark it with 1            int maxDiv = (int)Math.Floor(Math.Sqrt(toNumber));            int[] mark = new int[list.Length];            for (int i = 0; i < list.Length; i++)            {                for (int j = 2; j <= maxDiv; j++)                {                    if ((list[i] != j) && (list[i] % j == 0))                    {                        mark[i] = 1;                    }                }                                int iteration = list.Length / 100;                if ((i % iteration == 0) && (backgroundWorker != null))                {                                    if (backgroundWorker.CancellationPending)                    {                        // Return without doing any more work.                        return null;                                          }                    if (backgroundWorker.WorkerReportsProgress)                    {                        //float progress = ((float)(i + 1)) / list.Length * 100;                        backgroundWorker.ReportProgress(i / iteration);                        //(int)Math.Round(progress));                    }                }            }            //create new array that contains only the primes, and return that array            int primes = 0;            for (int i = 0; i < mark.Length; i++)            {                if (mark[i] == 0) primes += 1;            }            int[] ret = new int[primes];            int curs = 0;            for (int i = 0; i < mark.Length; i++)            {                if (mark[i] == 0)                {                    ret[curs] = list[i];                    curs += 1;                }            }            if (backgroundWorker != null && backgroundWorker.WorkerReportsProgress)            {                backgroundWorker.ReportProgress(100);            }            return ret;        }            }}

D31_02_BackgroundWorker类