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     }




 

 



posted @ 2012-04-09 11:35  January  阅读(1430)  评论(1编辑  收藏  举报