原文: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方法中的一下代码段

  1. this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
  2. (ThreadStart)delegate()
  3. {
  4. //txt.Text = "Here is some new text.";
  5. UpdateText();
  6. }
  7. );
  1. 可以用一下代码来替换,以增加代码的可读性
  1. private delegate void UpdateTextDelegate();
  2. this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,new UpdateTextDelegate(UpdateText));
  1. 其实,这与上篇实例中应用的方法是相同的。

    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. }
  1. 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 = ; i < list.Length; i++)
  14. {
  15. list[i] = fromNumber;
  16. fromNumber += ;
  17. }
  18.  
  19. //find out the module for each item in list, divided by each d, where
  20. //d is < or == to sqrt(to)
  21. //if the remainder is 0, the nubmer is a composite, and thus
  22. //we mark its position with 0 in the marks array,
  23. //otherwise the number is a prime, and thus mark it with 1
  24.  
  25. //Math.Floor 返回小于或等于指定双精度浮点数的最大整数。
  26. int maxDiv = (int)Math.Floor(Math.Sqrt(toNumber));
  27.  
  28. int[] mark = new int[list.Length];
  29.  
  30. for (int i = ; i < list.Length; i++)
  31. {
  32. for (int j = ; j <= maxDiv; j++)
  33. {
  34.  
  35. if ((list[i] != j) && (list[i] % j == ))
  36. {
  37. mark[i] = ;
  38. }
  39.  
  40. }
  41.  
  42. int iteration = list.Length / ;
  43. if ((i % iteration == ) && (backgroundWorker != null))
  44. {
  45. //BackgroundWorker.CancellationPending获取一个值,指示应用程序是否已请求取消后台操作。
  46. if (backgroundWorker.CancellationPending)
  47. {
  48. // Return without doing any more work.
  49. return null;
  50. }
  51.  
  52. //BackgroundWorker.WorkerReportsProgress 获取或设置一个值,该值指示 System.ComponentModel.BackgroundWorker 能否报告进度更新。
  53. if (backgroundWorker.WorkerReportsProgress)
  54. {
  55. //float progress = ((float)(i + 1)) / list.Length * 100;
  56. //BackgroundWorker.ReportProgress 引发 System.ComponentModel.BackgroundWorker.ProgressChanged 事件。
  57. backgroundWorker.ReportProgress(i / iteration);
  58. //(int)Math.Round(progress));
  59. }
  60. }
  61.  
  62. }
  63.  
  64. //create new array that contains only the primes, and return that array
  65. int primes = ;
  66. for (int i = ; i < mark.Length; i++)
  67. {
  68. if (mark[i] == )
  69. primes += ;
  70.  
  71. }
  72.  
  73. int[] ret = new int[primes];
  74. int curs = ;
  75. for (int i = ; i < mark.Length; i++)
  76. {
  77. if (mark[i] == )
  78. {
  79. ret[curs] = list[i];
  80. curs += ;
  81. }
  82. }
  83.  
  84. if (backgroundWorker != null && backgroundWorker.WorkerReportsProgress)
  85. {
  86. backgroundWorker.ReportProgress();
  87. }
  88.  
  89. return ret;
  90.  
  91. }
  92.  
  93. }

  1. 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. <TextBlock Margin="5">From:</TextBlock>
  28. <TextBox Name="txtFrom" Grid.Column="1" Margin="5">1</TextBox>
  29. <TextBlock Grid.Row="1" Margin="5">To:</TextBlock>
  30. <TextBox Name="txtTo" Grid.Row="1" Grid.Column="1" Margin="5">500000</TextBox>
  31.  
  32. <StackPanel Orientation="Horizontal"
  33. Grid.Row="2" Grid.Column="1">
  34. <Button Name="cmdFind"
  35. Margin="5" Padding="3"
  36. Click="cmdFind_Click">Find Primes</Button>
  37. <Button Name="cmdCancel"
  38. Margin="5" Padding="3" IsEnabled="False"
  39. Click="cmdCancel_Click">Cancel</Button>
  40. </StackPanel>
  41.  
  42. <TextBlock Grid.Row="3" Margin="5">Results:</TextBlock>
  43. <ListBox Name="lstPrimes" Grid.Row="3" Grid.Column="1"
  44. Margin="5"></ListBox>
  45.  
  46. <ProgressBar Name="progressBar"
  47. Grid.Row="4" Grid.ColumnSpan="2"
  48. Margin="5" VerticalAlignment="Bottom" MinHeight="20"
  49. Minimum="0" Maximum="100" Height="20"></ProgressBar>
  50. </Grid>
  51. </Window>

  1. 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 = ;
  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. }


WPF中的多进程(Threading)处理实例(二)的更多相关文章

  1. WPF中的多进程(Threading)处理实例(一)

    原文:WPF中的多进程(Threading)处理实例(一) 说明:希望通过揣摩这些案例,能进一步了解进程的工作原理. 1.方法一描述的是在同一窗口中,在计算素数的同时而不影响Canvas的工作. 方法 ...

  2. 在WPF中自定义你的绘制(二)

    原文:在WPF中自定义你的绘制(二)   在WPF中自定义你的绘制(二)                                                                 ...

  3. WPF中的命令与命令绑定(二)

    原文:WPF中的命令与命令绑定(二) WPF中的命令与命令绑定(二)                                              周银辉在WPF中,命令(Commandi ...

  4. Python中的多进程与多线程(二)

    在上一章中,学习了Python多进程编程的一些基本方法:使用跨平台多进程模块multiprocessing提供的Process.Pool.Queue.Lock.Pipe等类,实现子进程创建.进程池(批 ...

  5. java中注解的使用与实例 (二)

    java 注解,从名字上看是注释,解释.但功能却不仅仅是注释那么简单.注解(Annotation) 为我们在代码中添加信息提供了一种形式化的方法,是我们可以在稍后 某个时刻方便地使用这些数据(通过 解 ...

  6. 二维图形的矩阵变换(二)——WPF中的矩阵变换基础

    原文:二维图形的矩阵变换(二)--WPF中的矩阵变换基础 在前文二维图形的矩阵变换(一)——基本概念中已经介绍过二维图像矩阵变换的一些基础知识,本文中主要介绍一下如何在WPF中进行矩阵变换. Matr ...

  7. 线程在WPF中的使用

    项目中可能会有这样的需求,一直获取新的某个数据信息,但仍不影响其他的操作功能,这时就用到了线程,获取新数据放到线程中操作,对其他操作不产生影响,下面就以随机获取数组中项为例解说WPF中使用线程这一实例 ...

  8. 在WPF中自定义你的绘制(一)

    原文:在WPF中自定义你的绘制(一)   在WPF中自定义你的绘制(一)                                                                 ...

  9. 在WPF中自定义控件(3) CustomControl (下)

    原文:在WPF中自定义控件(3) CustomControl (下)   在WPF中自定义控件(3) CustomControl (下)                                 ...

随机推荐

  1. html中如何实现表格移入移出时背景颜色改变?(两种方法)

    html中如何实现表格移入移出时背景颜色改变?(两种方法) 一.总结 1.通过css的table标签的hover属性: 10 #tab:hover{ 11 background: green 12 } ...

  2. 如何安全退出多个Activity

    我们在项目开发的时候可能会遇到安全退出应用的场景,如何能够安全退出多个Activity?网上有很多方法,如下: 1.抛异常退出 该方法通过抛异常,使程序Force Close.验证可以,但是,需要解决 ...

  3. cocos2d-x 3.4 中文乱码解决之道

    cocos2dx 中文乱码解决之道 须要引入五个文件 1.iconv.h 2.iconvString.cpp 3.iconvString.h 4.iconv.dll 5.libiconv.lib 完整 ...

  4. JFinal redis cluster集群插件

    JFinal redis cluster集群插件 JFinal 框架到了2.1版本号,可是依旧仅仅支持redis的主从集群,没有看到Cluster集群的插件.笔者照着主从的插件方式,改了改,实现了个简 ...

  5. [Ramda] Rewrite if..else with Ramda ifElse

    From: const onSeachClick = (searchTerm) => { if(searchTerm !== '') { searchForMovies(searchTerm) ...

  6. [Erlang 0057] Erlang 排错利器: Erlang Crash Dump Viewer

    http://www.cnblogs.com/me-sa/archive/2012/04/28/2475556.html Erlang Crash Dump Viewer真的是排错的天兵神器,还记得我 ...

  7. 【 D3.js 高级系列 — 2.0 】 机械图 + 人物关系图

    机械图(力路线图)结合老百姓的关系图中的生活,这是更有趣. 本文将以此为证据,所列的如何图插入外部的图像和文字的力学. 在[第 9.2 章]中制作了一个最简单的力学图.其后有非常多朋友有疑问,基本的问 ...

  8. Apacheserver自己定义404页面的两种方法以及.htaccess的重要命令总结

    Apacheserver自己定义404错误页面有两种方法: 第一种方法最简单,直接在Apache的httpd.conf下进行配置改动命令,改动的内容请參看.htaccess命令写法中的自己定义错误页面 ...

  9. Method and apparatus for encoding data to be self-describing by storing tag records describing said data terminated by a self-referential record

    A computer-implemented method and apparatus in a computer system of processing data generated by a f ...

  10. Hibernate——(6)延迟加载机制

    一.延迟加载机制的基本原理 当访问实体对象时,并不是立即到数据库中查找.而是在真正要使用实体对象的时候,才去数据库查询数据. 具备这样功能的方法 session.load(...) query.ite ...