原文: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 webview中的音乐的暂停与播放

    前段时间有这样一个需求,webview显示一个带音乐的网页,在播放音乐的时候进入第三方软件暂停播放,返回时继续播放.后来参考了两篇文章解决了这个问题. AudioManager audioManage ...

  2. 前端切图:调用百度地图API

    原型图 图片发自简书App <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> ...

  3. Weblogic中可以使用的脚本

    启动被管服务器的脚本 rm -rf ../servers/server5002/stage/* rm -rf ../servers/server5002/tmp/* sleep 20 USER_MEM ...

  4. 【u219】最长链

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 现给出一棵N个结点二叉树,问这棵二叉树中最长链的长度为多少,保证了1号结点为二叉树的根. [提示] 关 ...

  5. XMPP之ios即时通讯客户端开发-配置XMPP基本信息之工程代码(五)

    登录功能完成以后包含以下代码文件: AppDelegate.h AppDelegate.m LoginViewController.h LoginViewController.m LoginUser. ...

  6. Erlang epmd的角色以及使用

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

  7. cordova-plugin-android-update安卓版本更新插件使用

    原文:cordova-plugin-android-update安卓版本更新插件使用 安装插件,使用方法官方都有. 安卓7.0以上要在AndroidMainfest.xml里加一句 <uses- ...

  8. ajax的跨域请求问题:减少options请求

    服务器端在Response Headers里添加字段Access-Control-Max-Age: 86400 , "Access-Control-Max-Age"表明在86400 ...

  9. WPF--动态添加控件、访问控件

    //WPF窗口采用默认的Grid布局控件,其“Name”值为“grid1”,在“grid1”中添加三个Button按钮.动态添加控件并访问这些控件的代码如下: private void button1 ...

  10. twemproxy分片处理原理--剖析twemproxy代码正编

    twemproxy在redis上能处理多命令流程只有mset,mget,del的命令,例如mset的话是mset k1 v1 k2 v2 k3 k3,mget的话是mget k1 k2 k3,del的 ...