线程处理使程序能够执行并发处理,以便它可以做多个操作一次。节省开发人员从线程处理困难的方式,设计了 WPF (窗口演示文稿基金会)。这篇文章可以帮助理解线程在 WPF 中的正确用法。

WPF 内部线程和规则

所有 WPF 应用程序中都运行两个线程:

  1. 为呈现-它在后台运行,所以,它被隐藏。
  2. 用于管理 UI 界面 (UI 线程) — —

大多数 WPF 对象与 UI 线程被束缚。它接收输入、 绘制屏幕、 运行的代码和处理事件。

WPF 支持单线程单元模型,有以下规则:

  1. 一个线程在整个应用程序中运行,并拥有所有 WPF 对象。
  2. WPF 元素有其他线程不能彼此交互的线程亲和手段。
  3. 具有线程关联的 WPF 对象从调度程序对象派生。

线程处理在 WPF 中由开发商

而在 WPF 开发人员都需要如此管理线程在某些情况下创建应用程序,它提供了一些方法来处理,并在不同的场景上的应用程序中使用的线程。以下是为处理线程的两种方式:

  1. 调度程序
  2. 后台辅助线程。

调度程序

调度程序是System.Windows.Threading 的一个实例。调度员类。它拥有应用程序线程和管理队列的工作项。它的每个优先,以执行 UI 操作以 fifo (先进先出) 的方式。它并不创建新的线程。它不是多线程的。

每个视觉 WPF 对象从DispatcherObject派生。它是一个链接到 DispatcherObject 类的对象。以下是 DispatcherObject 类的成员:

(1) 属性

  1. 调度员: 它获取调度程序。

(2) 方法:

在 DispatcherObject Class 中有几种方法。一些重要的方法如下:

  1. Checkaccess 方法 (): 它返回 true,则代码是一个正确的线程使用的对象。
  2. VerifyAccess (): 如果是没有的代码是在使用对象否则为会引发与"能反转"正确的线程上。
  3. 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 的执行。以下是某些情况下可以使用后台辅助线程的场合:

  1. 如果用户想要在特定的操作响应 UI 和面孔延误。
  2. 数据下载。
  3. 数据库事务。

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%

..........................

调度程序和后台辅助线程之间的区别:

  1. 后台辅助线程执行的代码在同一时间在一个单独的线程中调用它。调度程序处理的事情要做每一次队列时,它可自动同步和 WPF 应用程序的主线程。
  2. 后台辅助线程在单独的线程中执行与 WPF 应用程序的 UI 线程调度程序运行的同时。
  3. 如果你想要在后台运行操作,向用户界面,使用一个后台工作人员但使用调度程序封送回对 WPF UI 的更新。

在 WPF 中的线程的更多相关文章

  1. WPF中的线程使用

    原文:WPF中的线程使用 简介 但凡涉及到图形界面,往往的设计都是不支持或者不推荐使用多个线程操作界面内容.而且通常会有一个专门的线程调度器来处理任务线程和界面线程的问题.下面提供两个两个方案. 使用 ...

  2. 线程在WPF中的使用

    项目中可能会有这样的需求,一直获取新的某个数据信息,但仍不影响其他的操作功能,这时就用到了线程,获取新数据放到线程中操作,对其他操作不产生影响,下面就以随机获取数组中项为例解说WPF中使用线程这一实例 ...

  3. WPF中窗口控件的跨线程调用

    在WinForm中,我们要跨线程访问窗口控件,只需要设置属性CheckForIllegalCrossThreadCalls = false;即可. 在WPF中要麻烦一下,同样的不允许跨线程访问,因为没 ...

  4. WPF非UI线程中调用App.Current.MainWindow.Dispatcher提示其他线程拥有此对象,无权使用。

    大家都知道在WPF中对非UI线程中要处理对UI有关的对象进行操作,一般需要使用委托的方式,代码基本就是下面的写法 App.Current.MainWindow.Dispatcher.Invoke(ne ...

  5. WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object)

    原文 WPF 中那些可跨线程访问的 DispatcherObject(WPF Free Threaded Dispatcher Object) 众所周知的,WPF 中多数对象都继承自 Dispatch ...

  6. 将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本)

    原文:将 C++/WinRT 中的线程切换体验带到 C# 中来(WPF 版本) 如果你要在 WPF 程序中使用线程池完成一个特殊的任务,那么使用 .NET 的 API Task.Run 并传入一个 L ...

  7. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  8. 【WPF】 Timer与 dispatcherTimer 在wpf中你应该用哪个?

    源:Roboby 1.timer或重复生成timer事件,dispatchertimer是集成到队列中的一个时钟.2.dispatchertimer更适合在wpf中访问UI线程上的元素 3.Dispa ...

  9. WinForm与WPF下跨线程调用控件

    Winform下: public delegate void UpadataTextCallBack(string str,TextBox text); public void UpadtaText( ...

随机推荐

  1. <opengl>使用glu绘制二次曲面

    绘制二次曲面通常要以下四步:   1.首先我们创建一个二次方程状态对象 GLUquadricObj *m_pObj;    //保存绘图模式.法线模式.法线朝向.纹理等信息 //创建二次方程状态对象 ...

  2. docker镜像管理基础

    [root@node01 ~]# docker pull quay.io/coreos/flannel:v0.10.0-amd64 v0.10.0-amd64: Pulling from coreos ...

  3. Codefroces 762A k-th divisor 数论

    Codeforces 762A 题目大意: 给定两个正整数n,k\((n \le 10^{15},k\leq10^9)\),求n的从小到大的第k个约数,无解输出-1 分析: 我们会自然而然地想到找出n ...

  4. MongoDB4.0.0的安装配置—windows

    一.背景 由于要学习MongoDB,所以就下载了最新的MongoDB 的Community Server版的4.0.0版本.可能是新的版本的缘故,在安装配置上与MongoDB3有许多不同,而且在3中的 ...

  5. MySQL 5.7新特性

    新增特性 Security improvements. MySQL.user表新增plugin列,且若某账户该字段值为空则账户不能使用.从低版本MySQL升级至MySQL5.7时要注意该问题,且建议D ...

  6. Standby Redo Log 的设定原则、创建、删除、查看、归档位置

    设定: 1.每个standby redo log file 至少要和primary database的redo log 一样大,为了方便管理,Oracle 建议主备库的redo log 设置成一样的大 ...

  7. 洛谷P3373线段树模板2

    题目:https://www.luogu.org/problemnew/show/P3373 带乘的线段树,更新时把加的标记也乘一下,然后取值时先乘后加. 代码如下: #include<iost ...

  8. bootstrap模版兼容IE浏览器代码嵌入

    1.  bootstrap模板为使IE6.7.8版本(IE9以下版本)浏览器兼容html5新增的标签,引入下面代码文件即可. <script src="https://oss.maxc ...

  9. Spring boot 学习 五:domain的定义

    一 public class City implements Serializable 实现了Sericalizable接口,只是一种标志.表示可以被序列化. java的ObjectOutputStr ...

  10. [hiho1586]Minimum

    题意:区间内乘积最小值,带修改.解题关键:线段树裸题,考场上以为x y必须不等,还维护了次小值,尼玛嗨尼玛嗨,划水一整场,心态爆炸. 注意坐标需要+1 #include<cstdio> # ...