• 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     }






  • 相关阅读:
    嵌套矩形
    Multiplication Puzzle
    animate.css在vue项目中的使用
    服务器相关知识
    webpack-cli安装和插件的安装
    新买阿里云linux服务器如何设置账号密码xshell远程登陆
    主流请求库axios库的使用
    什么是回调函数
    js------match() 方法
    cookie
  • 原文地址:https://www.cnblogs.com/January/p/2438668.html
Copyright © 2020-2023  润新知