在 WPF 中的线程
线程处理使程序能够执行并发处理,以便它可以做多个操作一次。节省开发人员从线程处理困难的方式,设计了 WPF (窗口演示文稿基金会)。这篇文章可以帮助理解线程在 WPF 中的正确用法。
WPF 内部线程和规则
所有 WPF 应用程序中都运行两个线程:
- 为呈现-它在后台运行,所以,它被隐藏。
- 用于管理 UI 界面 (UI 线程) — —
大多数 WPF 对象与 UI 线程被束缚。它接收输入、 绘制屏幕、 运行的代码和处理事件。
WPF 支持单线程单元模型,有以下规则:
- 一个线程在整个应用程序中运行,并拥有所有 WPF 对象。
- WPF 元素有其他线程不能彼此交互的线程亲和手段。
- 具有线程关联的 WPF 对象从调度程序对象派生。
线程处理在 WPF 中由开发商
而在 WPF 开发人员都需要如此管理线程在某些情况下创建应用程序,它提供了一些方法来处理,并在不同的场景上的应用程序中使用的线程。以下是为处理线程的两种方式:
- 调度程序
- 后台辅助线程。
调度程序
调度程序是System.Windows.Threading 的一个实例。调度员类。它拥有应用程序线程和管理队列的工作项。它的每个优先,以执行 UI 操作以 fifo (先进先出) 的方式。它并不创建新的线程。它不是多线程的。
每个视觉 WPF 对象从DispatcherObject派生。它是一个链接到 DispatcherObject 类的对象。以下是 DispatcherObject 类的成员:
(1) 属性
- 调度员: 它获取调度程序。
(2) 方法:
在 DispatcherObject Class 中有几种方法。一些重要的方法如下:
- Checkaccess 方法 (): 它返回 true,则代码是一个正确的线程使用的对象。
- VerifyAccess (): 如果是没有的代码是在使用对象否则为会引发与"能反转"正确的线程上。
- GetType (): 它获取当前实例的类型。
WPF 对象调用VerifyAccess () 频繁地项目本身。
我们为什么需要调度程序?
将澄清的调度员在 WPF 应用程序中需要一个例子:
using System;
using System.Threading;
using System.Windows; namespace WpfApplication1
{
/// <summary>
/// Interaction logic for WPF UI Upadation using
/// thread.
/// </summary> public partial class MainWindow : Window
{ public MainWindow()
{
InitializeComponent();
} private void MyButton_Click(object sender, RoutedEventArgs e)
{
Thread thread = new Thread(UpdateText);
thread.Start();
} private void UpdateText()
{
Thread.Sleep(TimeSpan.FromSeconds());
TxtName.Text = "Hello Geeks !";
}
}
}
现在,这是一个错误的代码,因为将会在一个新线程,执行UpdateText()的方法,不允许线程访问 WPF 对象。
"VerifyAccess()"方法调用和不能被"加载"。
以上代码的校正:
using System;
using System.Threading;
using System.Windows; namespace WpfApplication1
{
/// <summary>
/// Interaction logic for WPF UI Upadation using
/// Dispatcher.
/// </summary> public partial class MainWindow : Window
{
public MainWindow()
{ InitializeComponent();
} private void MyButton_Click(object sender, RoutedEventArgs e)
{ Thread thread = new Thread(UpdateText);
thread.Start();
} private void UpdateText()
{
Thread.Sleep(TimeSpan.FromSeconds());
this.Dispatcher.BeginInvoke(new Action(() =>
{
TxtName.Text = "Hello Geeks !";
}));
}
}
}
所以,调度程序是与线程更新 WPF 用户界面的最佳途径。
后台辅助线程
它是非常有利的耗时的任务。它在同一时间执行的代码。它是在一个单独的线程中调用。它会自动与应用程序的主线程进行同步。
它用来在后台运行操作和延迟到 UI 的执行。以下是某些情况下可以使用后台辅助线程的场合:
- 如果用户想要在特定的操作响应 UI 和面孔延误。
- 数据下载。
- 数据库事务。
BackgroundWorker 是在System.ComponentModel下的类。它将执行一个单独的线程上运行。
using System;
using System.ComponentModel;
using System.Threading; namespace BackGroundWorkerExample
{ /// <summary>
/// It implements backgroundworker.
/// </summary> class Program
{ private static BackgroundWorker backgroundWorker;
static void Main(string[] args)
{
backgroundWorker = new BackgroundWorker
{
WorkerReportsProgress = true,
WorkerSupportsCancellation = true
}; //Event creation. //For the performing operation in the background. backgroundWorker.DoWork += backgroundWorker_DoWork; //For the display of operation progress to UI. backgroundWorker.ProgressChanged += backgroundWorker_ProgressChanged; //After the completation of operation. backgroundWorker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted; backgroundWorker.RunWorkerAsync("Press Enter in the next 5 seconds to Cancel operation:"); Console.ReadLine(); if (backgroundWorker.IsBusy)
{
backgroundWorker.CancelAsync();
Console.ReadLine();
}
}
现在,在背景中执行操作。
/// <summary>
/// Performs operation in the background.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param> static void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{ for (int i = ; i < ; i++)
{
if (backgroundWorker.CancellationPending)
{
e.Cancel = true;
return;
} backgroundWorker.ReportProgress(i);
Thread.Sleep();
e.Result = ;
}
}
为执行操作进度的更改事件。
/// <summary>
/// Displays Progress changes to UI .
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param> static void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
Console.WriteLine("Completed" + e.ProgressPercentage + "%");
}
通过使用 Runworker 完成事件显示结果:
1 /// <summary>
2 /// Displays result of background performing operation.
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="e"></param>
6
7 static void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
8 {
9 if (e.Cancelled)
10 {
11 Console.WriteLine("Operation Cancelled");
12 }
13 else if (e.Error != null)
14 {
15 Console.WriteLine("Error in Process :" + e.Error);
16 }
17 else
18 {
19 Console.WriteLine("Operation Completed :" + e.Result);
20 }
21
22 }
输出:
已完成的 0%
已完成的 1%
已完成的 2%
..........................
调度程序和后台辅助线程之间的区别:
- 后台辅助线程执行的代码在同一时间在一个单独的线程中调用它。调度程序处理的事情要做每一次队列时,它可自动同步和 WPF 应用程序的主线程。
- 后台辅助线程在单独的线程中执行与 WPF 应用程序的 UI 线程调度程序运行的同时。
- 如果你想要在后台运行操作,向用户界面,使用一个后台工作人员但使用调度程序封送回对 WPF UI 的更新。
在 WPF 中的线程的更多相关文章
- WPF中的线程使用
原文:WPF中的线程使用 简介 但凡涉及到图形界面,往往的设计都是不支持或者不推荐使用多个线程操作界面内容.而且通常会有一个专门的线程调度器来处理任务线程和界面线程的问题.下面提供两个两个方案. 使用 ...
- 线程在WPF中的使用
项目中可能会有这样的需求,一直获取新的某个数据信息,但仍不影响其他的操作功能,这时就用到了线程,获取新数据放到线程中操作,对其他操作不产生影响,下面就以随机获取数组中项为例解说WPF中使用线程这一实例 ...
- WPF中窗口控件的跨线程调用
在WinForm中,我们要跨线程访问窗口控件,只需要设置属性CheckForIllegalCrossThreadCalls = false;即可. 在WPF中要麻烦一下,同样的不允许跨线程访问,因为没 ...
- WPF非UI线程中调用App.Current.MainWindow.Dispatcher提示其他线程拥有此对象,无权使用。
大家都知道在WPF中对非UI线程中要处理对UI有关的对象进行操作,一般需要使用委托的方式,代码基本就是下面的写法 App.Current.MainWindow.Dispatcher.Invoke(ne ...
- WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object)
原文 WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object) 众所周知的,WPF 中多数对象都继承自 Dispatch ...
- 将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本)
原文:将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本) 如果你要在 WPF 程序中使用线程池完成一个特殊的任务,那么使用 .NET 的 API Task.Run 并传入一个 L ...
- MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信
MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...
- 【WPF】 Timer与 dispatcherTimer 在wpf中你应该用哪个?
源:Roboby 1.timer或重复生成timer事件,dispatchertimer是集成到队列中的一个时钟.2.dispatchertimer更适合在wpf中访问UI线程上的元素 3.Dispa ...
- WinForm与WPF下跨线程调用控件
Winform下: public delegate void UpadataTextCallBack(string str,TextBox text); public void UpadtaText( ...
随机推荐
- bzoj4555: 求和sum 快速傅立叶变换
题目大意 给定\(S(n,m)\)表示第二类斯特林数,定义函数\(f(n)\) \[f(n) = \sum_{i=0}^n\sum_{j=0}^iS(i,j)*2^j*(j!)\] 给定正整数\(n, ...
- MongoDB中的一些坑(最好不要用)
MongoDB 是目前炙手可热的 NoSQL 文档型数据库,它提供的一些特性很棒:如自动 failover 机制,自动 sharding,无模式 schemaless,大部分情况下性能也很棒.但是薄荷 ...
- linux下Redis以及c++操作
使用不同的语言,redis支持不同的编程语言,但是调用了不同的redis包,例如: java对应jedis: php对应phpredis: C++对应的则是hredis. 安装Redis 上篇博客已经 ...
- Thrift简析
Thrift源于大名鼎鼎的facebook之手,在2007年facebook提交Apache基金会将Thrift作为一个开源项目,对于当时的facebook来说创造thrift是为了解决faceboo ...
- 用nexus搭建自己的maven私有仓库
用nexus搭建自己的maven私有仓库 刚安装nexus时,nexus启动失败,启动不到1分钟,自动停止.后来查找到了原因: Java 6 Support EOLOracle's support ...
- 百度地图API的第一次接触——自定义控件
1.定义一个控件类,即function function ZoomControl(){ // 设置默认停靠位置和偏移量 this.defaultAnchor = BMAP_ANCHOR_TOP_LEF ...
- C# 获取Console的输入和输出 数据 (异步)
using System ; using System .Diagnostics; using System .IO; class Program { static void Main() ...
- Iptables防火墙面试题
Iptables防火墙面试题 第1章 (一)基础口试题 1.1 详述 iptales 工作流程以及规则过滤顺序? 1.防火墙是一层层过滤的.实际是按照配置规则的顺序从上到下,从前到后进行过滤的. 2. ...
- ng2中router-outlet用法
说明:router-outlet 是应用中的路由插座,一个页面中可以使用一个或多个router-outlet 1.只使用一个router-outlet 父组件: <router-outlet&g ...
- SQL 排序规则问题
http://blog.csdn.net/delphigbg/article/details/12744807 MSSQL排序规则总结 什么是排序规则呢? 排序规则根据特定语言和区域设置标准指定对 ...