在 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( ...
随机推荐
- 【LeetCode】039. Combination Sum
题目: Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all uniq ...
- 虚拟机VMware Workstation cannot connect to the virtual machine
解决方法: 从提示消息我们可以看到,问题在于VMware授权服务没有开启,具体处理方法如下: "This PC(我的电脑)"---右键"manage(管理)"- ...
- 【转】Pro Android学习笔记(九):了解Content Provider(下下)
Content provider作为信息的读出,比较常见的还有文件的读写,最基础的就是二进制文件的的读写,例如img文件,音频文件的读写.在数据库中存放了该文件的路径,我们可以通过ContentPro ...
- java——static声明方法注意事项
在使用 static 类型声明的方法时需要注意的是:如果在类中声明了一 static类型的属性,则此属性既可以在非 static 类型的方法中使用,也可以在 static类型的方法中使用.但用 sta ...
- 牛客多校5 A-gpa(01分数规划)
gpa 链接:https://www.nowcoder.com/acm/contest/143/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 262144K,其他语言 ...
- React Native环境搭建(iOS、Mac)
http://reactnative.cn/docs/0.42/getting-started.html#content 1.安装Homebrew Homebrew, Mac系统的包管理器,用于安装N ...
- 【原】spring+springmvc+mybatis整合
整合框架的代码结构: 最全约束: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=&q ...
- 无监督学习:Neighbor Embedding(邻域嵌套)
一 Manifold Learning 我们要做的是非线性的降维,data是分布在低维空间里面,只是被扭曲到了高维空间. 比如地球的表面是一个二维平面,但是被塞到一个三维空间中. Manifold就是 ...
- 最棒的Unity Github 项目收集(2016)
http://1darray.com/blog/2016/03/08/best-unity-github-repositories/ List of best public GitHub reposi ...
- HyperLedger Fabric 多机部署(一)
本文参考:http://www.lijiaocn.com/%E9%A1%B9%E7%9B%AE/2018/04/26/hyperledger-fabric-deploy.html 学习. 1.准备工 ...