在 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( ...
随机推荐
- 1095 Cars on Campus (30)(30 分)
Zhejiang University has 6 campuses and a lot of gates. From each gate we can collect the in/out time ...
- NCEE2018游记
前言 悠闲的高中生活结束啦.俺たちの戦いはこれからだ!(无误) Day0 看考场 听考前教育,前面还挺常规,后面讲了半个多小时相关法律,听了几句后实在没兴趣了,开始瞎想.那个人连续读了近一个小时也不嫌 ...
- VirtualBox下安装MacOS11
8.键盘选中 “简体中文” -- > "拼音模式".VirtualBox安装Mac OS 10.11 ,安装日期:2016 / 5 / 14 用虚拟机装黑苹果本人也装了不下3 ...
- Poj_1005_I Think I Need A HouseBoat
一.Description Fred Mapper is considering purchasing some land in Louisiana to build his house on. In ...
- mysql两主多从
1.实现目标 目标清单: 1)Master(192.168.31.230)为正常运行环境下的主库,为两个Slave(192.168.31.231和192.168.31.232)提供“主-从”复制功能: ...
- redis和memcache的比较
1.数据类型支持不同 与Memcached仅支持key-value结构不同,Redis支持的数据类型更丰富,同时支持list.set.hash等数据结构的存储: 2.内存管理不同 在Redis中,并不 ...
- Robot FrameWork基础学习(四) 元素定位
元素定位 对于web自动化测试来说,就是操作页面的各种元素,在操作元素之间需要先找到元素,换句话说就是定位元素. Selenium2Library提供了非常丰富的定位器: 虽然提供了这么多种定位方式, ...
- Primer回顾 数组和指针
数组和指针类似于vector和迭代器. 区别在于:数组的长度是固定的.数组一经创建,就不允许添加新的元素.指针则可以像迭代器一样用于遍历和检查数组中的元素. 设计良好的程序只有在强调速度时才在类实现的 ...
- JavaWeb_打包web应用war
使用下面的语句进行打包 jar -cvf aa.war news 打包之后的文件可以直接放在tomcat的webapps里面,一旦启动tomcat,会自动解压aa.war文件.
- iOS公司账号($99)/企业账号($299)申请
公司账号($99)与企业账号($299)申请基本大同小异,最主要的差别就在于入口不一样 一.注册Apple ID 在iOSAppStore个人开发者账号申请中已经介绍过注册App ID的流程,这里不再 ...