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

     //错误的处理
private void cmdBreakRules_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(UpdateTextWrong);
thread.Start();
} private void UpdateTextWrong()
{
txt.Text = "Here is some new text.";
} //正确的处理
private void cmdFollowRules_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(UpdateTextRight);
thread.Start();
} private void UpdateTextRight()
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,
(ThreadStart) delegate()
{
//txt.Text = "Here is some new text.";
UpdateText();
}
);
} private void UpdateText()
{ txt.Text = "这是更新后的文本。";
}

说明: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

  public class FindPrimesInput
{
public int To
{ get; set; } public int From
{ get; set; } public FindPrimesInput(int from, int to)
{
To = to;
From = from;
} }
2.2 Worker
Worker

  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 = ; i < list.Length; i++)
{
list[i] = fromNumber;
fromNumber += ;
} //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 //Math.Floor 返回小于或等于指定双精度浮点数的最大整数。
int maxDiv = (int)Math.Floor(Math.Sqrt(toNumber)); int[] mark = new int[list.Length]; for (int i = ; i < list.Length; i++)
{
for (int j = ; j <= maxDiv; j++)
{ if ((list[i] != j) && (list[i] % j == ))
{
mark[i] = ;
} } int iteration = list.Length / ;
if ((i % iteration == ) && (backgroundWorker != null))
{
//BackgroundWorker.CancellationPending获取一个值,指示应用程序是否已请求取消后台操作。
if (backgroundWorker.CancellationPending)
{
// Return without doing any more work.
return null;
} //BackgroundWorker.WorkerReportsProgress 获取或设置一个值,该值指示 System.ComponentModel.BackgroundWorker 能否报告进度更新。
if (backgroundWorker.WorkerReportsProgress)
{
//float progress = ((float)(i + 1)) / list.Length * 100;
//BackgroundWorker.ReportProgress 引发 System.ComponentModel.BackgroundWorker.ProgressChanged 事件。
backgroundWorker.ReportProgress(i / iteration);
//(int)Math.Round(progress));
}
} } //create new array that contains only the primes, and return that array
int primes = ;
for (int i = ; i < mark.Length; i++)
{
if (mark[i] == )
primes += ; } int[] ret = new int[primes];
int curs = ;
for (int i = ; i < mark.Length; i++)
{
if (mark[i] == )
{
ret[curs] = list[i];
curs += ;
}
} if (backgroundWorker != null && backgroundWorker.WorkerReportsProgress)
{
backgroundWorker.ReportProgress();
} return ret; } }

2.3BackgroundWorker XAML
XAML

 <Window x:Class="Multithreading.BackgroundWorkerTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Multithreading" Height="323.2" Width="305.6"
xmlns:cm="clr-namespace:System.ComponentModel;assembly=System"
>
<Window.Resources>
<cm:BackgroundWorker x:Key="backgroundWorker"
WorkerReportsProgress="True" WorkerSupportsCancellation="True"
DoWork="backgroundWorker_DoWork" ProgressChanged="backgroundWorker_ProgressChanged"
RunWorkerCompleted="backgroundWorker_RunWorkerCompleted"></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">From:</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" IsEnabled="False"
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>

2.4 CS code
  public partial class BackgroundWorkerTest : System.Windows.Window
{
public BackgroundWorkerTest()
{
InitializeComponent();
//BackgroundWorker 在单独的线程上执行操作
//Window.FindResource(object resourceKey)搜索具有指定密钥的资源,找不到则会引发异常
backgroundWorker = ((BackgroundWorker)this.FindResource("backgroundWorker"));
} private BackgroundWorker 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); //BackgroundWorker.CancellationPending 获取一个值,指示应用程序是否已请求取消后台操作。
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 = ;
} private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
//ProgressChangedEventArgs.ProgressPercentage 获取异步任务的进度百分比
progressBar.Value = e.ProgressPercentage;
} private void cmdCancel_Click(object sender, RoutedEventArgs e)
{
//BackgroundWorker.CancelAsync() 请求取消挂起后的操作
backgroundWorker.CancelAsync();
}
}


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. Android bitmap绘制文字自动换行

    public Bitmap getNewBitMap(String text) { Bitmap newBitmap = Bitmap.createBitmap(,, Config.ARGB_4444 ...

  2. [Javascript] Javascript 'in' opreator

    If you want to check whether a key is inside an Object or Array, you can use 'in': Object: const obj ...

  3. 微信公众号开发之怎样将本机IP映射成外网域名

    近期一个项目须要用到微信公众号的网页授权登录,在研究这个公众号的时候遇到各种困难,现将自己的一些心得总结一下. 我想进行微信公众号开发遇到的第一个困难就是微信公众号必须输入一个外网能够訪问的域名,在网 ...

  4. Erlang epmd的角色以及使用

    本文链接地址: Erlang epmd的角色以及使用 很多同学误会了epmd的作用,认为epmd就是erlang集群的协议,我来澄清下: Epmd是Erlang Port Mapper Daemon的 ...

  5. 微信支付-公众号支付H5调用支付详解

    微信公众号支付 最近项目需要微信支付,然后看了下微信公众号支付,,虽然不难,但是细节还是需要注意的,用了大半天时间写了个demo,并且完整的测试了一下支付流程,下面分享一下微信公众号支付的经验. 一. ...

  6. ServletContextListener和ContextLoaderListener的区别

    ServletContext 被 Servlet 程序用来与 Web 容器通信.例如写日志,转发请求.每一个 Web 应用程序含有一个Context,被Web应用内的各个程序共享.因为Context可 ...

  7. C# WPF 多个window 相互覆盖的次序控制 不用topmost

    原文:C# WPF 多个window 相互覆盖的次序控制 不用topmost   WindowInteropHelper mianHanel = new WindowInteropHelper(Mai ...

  8. [ACM] POJ 2689 Prime Distance (筛选范围大素数)

    Prime Distance Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 12811   Accepted: 3420 D ...

  9. HDU 1671 (字典树统计是否有前缀)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1671 Problem Description Given a list of phone number ...

  10. Android桌面悬浮窗效果实现,仿360手机卫士悬浮窗效果

    大家好,今天给大家带来一个仿360手机卫士悬浮窗效果的教程,在开始之前请允许我说几句不相干的废话. 不知不觉我发现自己接触Android已有近三个年头了,期间各种的成长少不了各位高手的帮助,总是有很多 ...