WPF中的多进程(Threading)处理实例(二)

WPF中的多进程(Threading)处理实例(二)

 

 

 

 

 

 

 

 

 

 

 1     //错误的处理

 2         private void cmdBreakRules_Click(object sender, RoutedEventArgs e)

 3         {

 4             Thread thread = new Thread(UpdateTextWrong);

 5             thread.Start();

 6         }

 7 

 8         private void UpdateTextWrong()

 9         {

10             txt.Text = "Here is some new text.";

11         }

12 

13         //正确的处理

14         private void cmdFollowRules_Click(object sender, RoutedEventArgs e)

15         {

16             Thread thread = new Thread(UpdateTextRight);

17             thread.Start();

18         }               

19 

20         private void UpdateTextRight()

21         {

22             this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,

23                 (ThreadStart) delegate()

24                 {

25                     //txt.Text = "Here is some new text.";

26                     UpdateText();

27                 }

28                 );

29         }

30 

31         private void UpdateText()

32         {

33 

34             txt.Text = "这是更新后的文本。";

35         }

 

说明:public DispatcherOperation BeginInvoke(DispatcherPriority priority, Delegate method);其中DispatcherPriority是从-1到10 的枚举值,10优先级最高。在UpdateTextRight方法中的一下代码段

            this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,

                (ThreadStart)delegate()

                {

                    //txt.Text = "Here is some new text.";

                    UpdateText();

                }

                );
可以用一下代码来替换,以增加代码的可读性
private delegate void UpdateTextDelegate();

this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,new UpdateTextDelegate(UpdateText));
其实,这与上篇实例中应用的方法是相同的。


2.BackgroundWorker

2.1FindPrimesInput
FindPrimesInput
 1  public class FindPrimesInput

 2     {        

 3         public int To

 4         { get; set; }

 5 

 6         public int From

 7         { get; set; }

 8 

 9         public FindPrimesInput(int from, int to)

10         {

11             To = to;

12             From = from;

13         }

14 

15     }
2.2 Worker
Worker
 1  public class Worker

 2     {

 3         public static int[] FindPrimes(int fromNumber, int toNumber)

 4         {

 5             return FindPrimes(fromNumber, toNumber, null);

 6         }

 7 

 8         public static int[] FindPrimes(int fromNumber, int toNumber, System.ComponentModel.BackgroundWorker backgroundWorker)

 9         {

10             int[] list = new int[toNumber - fromNumber];

11 

12             // Create an array containing all integers between the two specified numbers.

13             for (int i = 0; i < list.Length; i++)

14             {

15                 list[i] = fromNumber;

16                 fromNumber += 1;

17             }

18 

19 

20             //find out the module for each item in list, divided by each d, where

21             //d is < or == to sqrt(to)

22             //if the remainder is 0, the nubmer is a composite, and thus

23             //we mark its position with 0 in the marks array,

24             //otherwise the number is a prime, and thus mark it with 1

25 

26             //Math.Floor 返回小于或等于指定双精度浮点数的最大整数。

27             int maxDiv = (int)Math.Floor(Math.Sqrt(toNumber));

28 

29             int[] mark = new int[list.Length];

30 

31             for (int i = 0; i < list.Length; i++)

32             {

33                 for (int j = 2; j <= maxDiv; j++)

34                 {

35 

36                     if ((list[i] != j) && (list[i] % j == 0))

37                     {

38                         mark[i] = 1;

39                     }

40 

41                 }

42 

43                 int iteration = list.Length / 100;

44                 if ((i % iteration == 0) && (backgroundWorker != null))

45                 {

46                     //BackgroundWorker.CancellationPending获取一个值,指示应用程序是否已请求取消后台操作。

47                     if (backgroundWorker.CancellationPending)

48                     {

49                         // Return without doing any more work.

50                         return null;                      

51                     }

52 

53                     //BackgroundWorker.WorkerReportsProgress 获取或设置一个值,该值指示 System.ComponentModel.BackgroundWorker 能否报告进度更新。

54                     if (backgroundWorker.WorkerReportsProgress)

55                     {

56                         //float progress = ((float)(i + 1)) / list.Length * 100;

57                         //BackgroundWorker.ReportProgress 引发 System.ComponentModel.BackgroundWorker.ProgressChanged 事件。

58                         backgroundWorker.ReportProgress(i / iteration);

59                         //(int)Math.Round(progress));

60                     }

61                 }

62 

63             }

64 

65             //create new array that contains only the primes, and return that array

66             int primes = 0;

67             for (int i = 0; i < mark.Length; i++)

68             {

69                 if (mark[i] == 0)

70                     primes += 1;

71 

72             }

73 

74             int[] ret = new int[primes];

75             int curs = 0;

76             for (int i = 0; i < mark.Length; i++)

77             {

78                 if (mark[i] == 0)

79                 {

80                     ret[curs] = list[i];

81                     curs += 1;

82                 }

83             }

84 

85             if (backgroundWorker != null && backgroundWorker.WorkerReportsProgress)

86             {

87                 backgroundWorker.ReportProgress(100);

88             }

89 

90             return ret;

91 

92         }

93 

94         

95     }

2.3BackgroundWorker XAML
XAML
 1 <Window x:Class="Multithreading.BackgroundWorkerTest"

 2     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

 3     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

 4     Title="Multithreading" Height="323.2" Width="305.6"

 5     xmlns:cm="clr-namespace:System.ComponentModel;assembly=System"

 6     >

 7     <Window.Resources>

 8         <cm:BackgroundWorker x:Key="backgroundWorker"

 9           WorkerReportsProgress="True" WorkerSupportsCancellation="True"

10           DoWork="backgroundWorker_DoWork" ProgressChanged="backgroundWorker_ProgressChanged" 

11           RunWorkerCompleted="backgroundWorker_RunWorkerCompleted"></cm:BackgroundWorker>

12     </Window.Resources>

13 

14     <Grid Margin="5">

15         <Grid.RowDefinitions>

16             <RowDefinition Height="Auto"></RowDefinition>

17             <RowDefinition Height="Auto"></RowDefinition>

18             <RowDefinition Height="Auto"></RowDefinition>

19             <RowDefinition></RowDefinition>

20             <RowDefinition Height="Auto"></RowDefinition>

21         </Grid.RowDefinitions>

22         <Grid.ColumnDefinitions>

23             <ColumnDefinition Width="Auto"></ColumnDefinition>

24             <ColumnDefinition></ColumnDefinition>

25         </Grid.ColumnDefinitions>

26 

27 

28         <TextBlock Margin="5">From:</TextBlock>

29         <TextBox Name="txtFrom" Grid.Column="1" Margin="5">1</TextBox>

30         <TextBlock Grid.Row="1" Margin="5">To:</TextBlock>

31         <TextBox Name="txtTo" Grid.Row="1" Grid.Column="1" Margin="5">500000</TextBox>

32 

33         <StackPanel Orientation="Horizontal"

34               Grid.Row="2" Grid.Column="1">

35             <Button Name="cmdFind"

36               Margin="5" Padding="3"

37               Click="cmdFind_Click">Find Primes</Button>

38             <Button Name="cmdCancel"

39               Margin="5" Padding="3" IsEnabled="False"

40               Click="cmdCancel_Click">Cancel</Button>

41         </StackPanel>

42 

43         <TextBlock Grid.Row="3" Margin="5">Results:</TextBlock>

44         <ListBox Name="lstPrimes" Grid.Row="3" Grid.Column="1" 

45                Margin="5"></ListBox>

46 

47 

48         <ProgressBar Name="progressBar"

49                Grid.Row="4" Grid.ColumnSpan="2"

50                Margin="5" VerticalAlignment="Bottom" MinHeight="20" 

51                Minimum="0" Maximum="100" Height="20"></ProgressBar>

52     </Grid>

53 </Window>

2.4 CS code
 1  public partial class BackgroundWorkerTest : System.Windows.Window

 2     {

 3         public BackgroundWorkerTest()

 4         {

 5             InitializeComponent();

 6             //BackgroundWorker 在单独的线程上执行操作

 7             //Window.FindResource(object resourceKey)搜索具有指定密钥的资源,找不到则会引发异常

 8             backgroundWorker = ((BackgroundWorker)this.FindResource("backgroundWorker"));

 9         }

10 

11         private BackgroundWorker backgroundWorker;

12 

13         private void cmdFind_Click(object sender, RoutedEventArgs e)

14         {

15             // Disable the button and clear previous results.

16             cmdFind.IsEnabled = false;

17             cmdCancel.IsEnabled = true;

18             lstPrimes.Items.Clear();            

19 

20             // Get the search range.

21             int from, to;

22             if (!Int32.TryParse(txtFrom.Text, out from))

23             {

24                 MessageBox.Show("Invalid From value.");

25                 return;

26             }

27             if (!Int32.TryParse(txtTo.Text, out to))

28             {

29                 MessageBox.Show("Invalid To value.");

30                 return;

31             }

32 

33             // Start the search for primes on another thread.

34             FindPrimesInput input = new FindPrimesInput(from, to);

35             backgroundWorker.RunWorkerAsync(input);

36         }

37 

38         private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)

39         {

40             // Get the input values.

41             FindPrimesInput input = (FindPrimesInput)e.Argument;

42 

43             // Start the search for primes and wait.

44             int[] primes = Worker.FindPrimes(input.From, input.To, backgroundWorker);

45 

46             //BackgroundWorker.CancellationPending 获取一个值,指示应用程序是否已请求取消后台操作。

47             if (backgroundWorker.CancellationPending)

48             {

49                 e.Cancel = true;

50                 return;

51             }

52 

53             // Return the result.

54             e.Result = primes;

55         }

56 

57         private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

58         {

59             if (e.Cancelled)

60             {

61                 MessageBox.Show("Search cancelled.");

62             }

63             else if (e.Error != null)

64             {

65                 // An error was thrown by the DoWork event handler.

66                 MessageBox.Show(e.Error.Message, "An Error Occurred");

67             }

68             else

69             {

70                 int[] primes = (int[])e.Result;

71                 foreach (int prime in primes)

72                 {

73                     lstPrimes.Items.Add(prime);

74                 }                

75             }

76             cmdFind.IsEnabled = true;

77             cmdCancel.IsEnabled = false;

78             progressBar.Value = 0;

79         }

80 

81         private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)

82         {

83             //ProgressChangedEventArgs.ProgressPercentage 获取异步任务的进度百分比

84             progressBar.Value = e.ProgressPercentage;

85         }

86 

87         private void cmdCancel_Click(object sender, RoutedEventArgs e)

88         {

89             //BackgroundWorker.CancelAsync() 请求取消挂起后的操作

90             backgroundWorker.CancelAsync();

91         }

92     }




 

 



你可能感兴趣的:(reading)