在 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( ...
随机推荐
- poj3784 Running Median[对顶堆]
由于我不会讲对顶堆,所以这里直接传上一个巨佬的学习笔记. 对顶堆其实还是很容易理解的,想这题的时候自己猜做法也能把没学过的对顶堆给想出来.后来了解,对顶堆主要还是动态的在线维护集合$K$大值.当然也可 ...
- visualVM远程监控JVM
对于完全没用使用过visualVM的初学者 环境:Windows PC上使用visualVM监控远端JVM @@@@jstatd方式连接@@@@ 1.Windows安装jdk,$JAVA_HOME/b ...
- BZOJ1926:[SDOI2010]粟粟的书架
浅谈主席树:https://www.cnblogs.com/AKMer/p/9956734.html 题目传送门:https://www.lydsy.com/JudgeOnline/problem.p ...
- hibernate学习 六 Hibernate缓存
缓存: 如果在集群环境下使用Hibernate时,(集群有节点A ,节点B) 当请求,发往A节点,A在数据库中修改了一条记录,然后节点B的缓存中如何实时的更新节点A修改的新数据 hi ...
- kindeditor Springmvc 整和解决图片上传问题
1. 在编辑页面引入js <script type="text/javascript" charset="utf-8" src="${baseP ...
- android apk 自我保护技术-完整性校验
关于防止android apk被反编译的技术我们前面已经讲了四种. 加壳技术 运行时修改字节码 伪加密 对抗JD-GUI 如果有不明白的可以查看我的博客的前四篇中关于这四种技术的介绍.接下来我们接着介 ...
- Elasticsearch学习概念之curl
curl,简单认为是可以在命令行下访问url的一个工具.即增删改查. curl是利用URL语法在命令行方式下工作的开源文件传输工具,使用curl可以简单实现常见的get/post请求. 查看curl的 ...
- 《精通Spring4.X企业应用开发实战》读后感第四章(BeanFactory和ApllicationContext)
- C 汉字处理
好像有个wchar_t类型的,这里不深究了,只研究char型(1个字符大小)的 1.定义 直接使用char,但每个汉字占据2个字符,所以必须以字符串形式存在 char s[10]; 2.定义时直接赋值 ...
- 微信小程序开发之拼接json数组字符串
直接上代码 : var imageitem; var imageitemstring=''; for(var i=0;i< that.data.fbimages.length;i ...