1.使用定时器异步修改

这是相对比较简单的方法

在Wpf中定时器使用DiapatcherTimer,不使用Timer原因:

在一个应用程序中,Timer会重复生成time事件,而DispatcherTimer是一个集成到了Dispatcher队列中的时钟,这可以使它被按照指定的时间间隔以指定的priority定期执行。

对于一个Timer时钟事件,系统并不能保证在时间间隔到达后被立即执行,但是能够确保在时间间隔到达之前不被执行。这是因为DispatcherTimer像其他操作一样被放置在了Dispatcher队列中。何时执行DispatcherTimer事件依赖于队列中的其他任务以及他们的优先级.

如果一个WPF应用程序使用了Timer时钟,那么它的事件必须在一个单独的时钟线程中运行,而不是在UI线程中,这对于WPF应用程序毫无用处——你没法在UI线程之外直接访问UI元素,而只能通过Invoke或者BeginInvoke将操作发送给Dispatcher 对象,委托Dispatcher去执行UI操作。

看到这里,你大概知道了为什么我们在WPF中应该用DispatcherTimer而不是Timer了:DispatcherTimer与Dispatcher运行于同一个线程中——UI线程,而且具有相同的DispatcherPriority优先级。

实例:

Xaml代码:

<Grid>
<TextBox x:Name="textBox" Padding="10"Height="45" TextWrapping="Wrap" Text="TextBox"VerticalAlignment="Top" Margin="10,105,10,0"/>
</Grid>

后台代码:

//启动其他线程处理,调用失败
//Task.Run(()=> {
//    DispatcherTimerHelper.DoWork(textBox);
//});//主线程调用成功
DispatcherTimerHelper.DoWork(textBox);

public class DispatcherTimerHelper
{//定时器,在指定事件内重复执行//在非主线程中,会出现异常,当前线程结束static DispatcherTimer _timer = new DispatcherTimer();public static void DoWork(TextBox textBlock){_timer.Interval = new TimeSpan(0, 0, 1);EventHandler event1 = new EventHandler(timer_Tick);_timer.Tick += event1;_timer.Tag = textBlock;_timer.Start();}public static void Stop(){_timer.Stop();}static void timer_Tick(object sender, EventArgs e){DispatcherTimer timer = sender as DispatcherTimer;TextBox box = timer.Tag as TextBox;box.Text = "张三"+DateTime.Now;}
}

2.使用BackgroundWorker

这个类是专门用于简化Windows Form程序与线程相关的问题设计的,同样适用于WPF程序.适合于一个长期的后台进程,支持进度通知,取消支持,完成通知等功能.

使用方法也很简单,创建一个BackfruopWorker实例,它有几个事件.

DoWork事件会在另外一个线程中执行,用RunWorkerAsync()启动.所以在这个事件中不要去处理修改界面的事情

RunWorkerCompleted事件,在DoWork事件返回时(正常或者异常返回),在图形的线程中执行,所以可以修改界面

ProgressChanged事件,使用ReportProgress()方法调用,同时是在图形界面的线程中执行,通常负责修改一下进度条什么的.而ReportProgress()方法,通常会在DoWork的事件中调用,然后给一个百分比的值.要使用这个功能,需要把WorkerReportsProgress属性设置成true

另外值得一说的是,要取消支持需要把WorkerSupportsCancellation属性设为true,使用CancelAsync()方法调用,但是这个调用不会终止进程,所以在DoWork事件中需要判断CancellationPending.

实例:

Xaml代码:

<StackPanel><ProgressBar Name="progressBar" Height="20" Width="200" Margin="10,80,20,10"></ProgressBar><Button Name="btnProcess" Width="100" Click="btnProcess_Click" Margin="5">开始后台任务</Button><Button Name="btnCancel" Width="100" Click="btnCancel_Click" Margin="5">取消后台任务</Button><Label x:Name="label" Content="Label" Margin="10"/>
</StackPanel>

C#后台代码:

/// <summary>
/// Thread9.xaml 的交互逻辑
/// </summary>
public partial class Thread9 : Window
{BackgroundWorker bgWorker = new BackgroundWorker();public Thread9(){InitializeComponent();bgWorker.WorkerReportsProgress = true;bgWorker.WorkerSupportsCancellation = true;//执行任务代码bgWorker.DoWork += DoWork_Handler;//执行过程触发bgWorker.ProgressChanged += ProgressChanged_Handler;//执行结束,或有异常结束触发bgWorker.RunWorkerCompleted += RunWorkerCompleted_Handler;}private void btnProcess_Click(object sender, RoutedEventArgs e){//开始执行if (!bgWorker.IsBusy){bgWorker.RunWorkerAsync();}}private void ProgressChanged_Handler(object sender, ProgressChangedEventArgs args){//在过程改变事件中可以修改UI内容progressBar.Value = args.ProgressPercentage;label.Content = "ProgressChanged方法执行完成" + args.ProgressPercentage;}private void DoWork_Handler(object sender, DoWorkEventArgs args){//在DoWork中修改UI同样会抛出异常//label.Content = "DoWork方法执行完成";BackgroundWorker worker = sender as BackgroundWorker;for (int i = 1; i <= 100; i++){if (worker.CancellationPending){args.Cancel = true;break;}else{//手动触发触发过程,代码执行
                worker.ReportProgress(i);Thread.Sleep(100);}}}private void RunWorkerCompleted_Handler(object sender, RunWorkerCompletedEventArgs args){progressBar.Value = 0;if (args.Cancelled){MessageBox.Show("后台任务已经被取消。", "消息");}else{MessageBox.Show("后台任务正常结束。", "消息");}}private void btnCancel_Click(object sender, RoutedEventArgs e){//结束执行
        bgWorker.CancelAsync();}
}

View Code

转载于:https://www.cnblogs.com/tianma3798/p/5766691.html

C# Wpf异步修改UI,多线程修改UI(二)相关推荐

  1. linux 进程间界面嵌套,WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)...

    WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验.如果希望做不同线程的 UI,大家也会想到使用另一个窗口来实现,让每个窗口拥有自己的 UI 线程.然而,就不能让 ...

  2. Android:Socket客户端开发,Android 的Socket客户端优化,Android非UI线程修改控件程序崩溃的问题

    一.Android:Socket客户端开发 创建一个工程 我们要做的是按下按键之后,去往服务器 (服务器) 或者我们自己写的服务器 ,给他发送一些预定好的东西 然后打开操作界面 然后修改一下 你要发送 ...

  3. GEE引擎传奇UI界面修改教程

    还记得明杰之前给大家分享了gom引擎UI界面编辑教程,今天给大家分享一下gee引擎UI界面修改教程 首先打开登录器生成器-客户端界面设置 在客户端界面设置这里可以自定义UI素材,也可以直接在原素材上编 ...

  4. Element UI样式修改之NavMenu导航菜单

    目录 Element UI样式修改之NavMenu导航菜单 一.成果展示 二.步骤 三.完整代码 Element UI样式修改之NavMenu导航菜单 一.成果展示 Element UI官网给出的例子 ...

  5. 怎么修改artifact_《Artifact》卡牌描述与游戏UI文字修改教程

    第1页: 展开 <Artifact>中有着许多的卡牌,由于<Artifact>采用了<DOTA2>的背景故事,这使得我们可以在这款卡牌游戏中看到许多熟悉的身影.下面 ...

  6. Android UI 统一修改Button控件的样式,以及其它系统控件的默认样式

    先介绍下修改原理:首先打开位于android.widget包下面的Button.java文件,这里有一句关键的代码如下: public Button(Context context, Attribut ...

  7. C# 多线程修改控件时遇到:创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke

    一般在多线程调用UI控件时,涉及到跨线程修改UI,需要使用委托,比如如下: this.Invoke((MethodInvoker)delegate{btnRefresh.Enabled = true; ...

  8. wxpython多线程_WxPython 4.0.4多线程访问UI

    最开始做框架的时候的需求就是多线程访问UI,以前在.NET WPF使用MVVM和数据驱动很容易做到,在JavaSwing中使用另类的观察者模式也实现了.在WxPython中使用观察者模式直接程序崩溃, ...

  9. android 异步回调中操作UI线程,UI同步、卡死阻塞等性能问题

    android开发中,回调无处不在,整个android开发的框架就是以回调机制建立起来的.如:activity,service,broadcast,fragment,view事件监听,baseadap ...

  10. C# Winform 跨线程更新UI控件常用方法汇总(多线程访问UI控件)

    概述 C#Winform编程中,跨线程直接更新UI控件的做法是不正确的,会时常出现"线程间操作无效: 从不是创建控件的线程访问它"的异常.处理跨线程更新Winform UI控件常用 ...

最新文章

  1. python和java哪个好学、零基础-老男孩零基础学习|python和java那个更有发展前景?...
  2. SD-WAN部署如何使用最后一英里连接?
  3. matlab添加多个legend
  4. php 字符串函数 教程_PHP 字符串获取 substr 与 strstr 函数
  5. makefile之伪目标(6)
  6. 【Python】pyinstaller安装失败的解决办法
  7. Asp.net 表单打印时的样式设置【原】
  8. python的opencv操作记录(七)——短时傅里叶变换(stft)
  9. 陀螺仪工作原理,你懂了吗?
  10. 刘昊威新作—东田造型三里屯VILLAGE概念店
  11. 王道计组——计算机的组成
  12. 电阻应变式测力压力称重传感器工作原理
  13. rdp(远程桌面协议)配置
  14. Unity模糊远处物体,近处清晰,景深效果
  15. Paper intensive reading (三):Interactions Between Food and Gut Microbiota: Impact on Human Health
  16. php概率计算_PHP 真实概率计算(百分比随机分配)
  17. asp毕业设计——基于vb+VB.NET+SQL Server的公文管理系统设计与实现(毕业论文+程序源码)——公文管理系统
  18. ip地址 @91.189.91.93 security AppCompatActivity(1024td
  19. JAVA - Map
  20. 网站云服务器租用带宽不足会引发哪些问题?

热门文章

  1. Linux truncate的使用方法介绍
  2. Mastering Unity 2D Game Development
  3. ios解决button重复点击的问题
  4. linux基础-第十六单元 yum管理RPM包
  5. 针对IE的CSS hack 全面 实用
  6. Spring MVC 4 - Hello World Tutorial
  7. sencha extjs4 command tools sdk
  8. ISA2006系列之三 详解防火墙的三种客户端(上)
  9. 扩展Editplus为Java IDE
  10. python面试题(5)--- 检测 字符串 是否可以转换成 数字