WPF多线程更新UI的一个解决途径
那么该如何解决这一问题呢?通常的做法是把耗时的函数放在线程池执行,然后切回主线程更新UI显示。前面的updateTime函数改写如下:
private async void updateTime()
{
while (true)
{
await Task.Run(() => Thread.Sleep(900));
textBlock.Text = DateTime.Now.ToString();
await Task.Delay(100);
}
}
这种方式能满足我们的大部分需求。但是,有的操作是比较耗时间的。例如,在多窗口实时监控的时候,我们就需要同时多十来个屏幕每秒钟各进行几十次的刷新,更新图像这个操作必须在UI线程上进行,并且它有非常耗时间,此时又会回到最开始的卡顿的情况。
看起来这个问题无法解决,实际上,WPF只是不允许跨线程访问程序,并非不允许多线程更新界面。我们大可以对每个视频监控窗口单独其一个独立的线程,在那个线程中进行更新操作,此时就不会影响到主线程。MSDN上有篇文章介绍了详细的操作:Multithreaded UI: HostVisual。用这种方式将原来的程序改写如下:
e)
{
();
(hostVisual);
.Content = content;
(() =>
{
(hostVisual);
();
control.Arrange((), content.RenderSize));
visualTarget.RootVisual = control;
System.Windows.Threading..Run();
}));
thread.SetApartmentState(.STA);
thread.IsBackground = ;
thread.Start();
}
{
child;
child)
{
)
);
.child = child;
AddVisualChild(child);
}
index)
{
;
}
VisualChildrenCount
{
1; }
}
}
这个里面用来了两个新的类:HostVisual、VisualTarget。以及自己写的一个VisualHost。MSDN上相关的解释,也不算难理解,这里就不多介绍了。最后,再来重构一下代码,把在新线程中创建控件的方式改写如下:
e)
{
createChildInNewThread<);
}
container)
()
{
();
(hostVisual);
container.Content = content;
(() =>
{
(hostVisual);
();
control.Arrange((), content.RenderSize));
visualTarget.RootVisual = control;
System.Windows.Threading..Run();
}));
thread.SetApartmentState(.STA);
thread.IsBackground = ;
thread.Start();
}
当然,我这个函数多了一些不必要的的限制:容器必须是ContentControl,子元素必须是UIElement。可以根据实际需要进行相关修改。
WPF多线程更新UI的一个解决途径的更多相关文章
- 拒绝卡顿——在WPF中使用多线程更新UI
原文:拒绝卡顿--在WPF中使用多线程更新UI 有经验的程序员们都知道:不能在UI线程上进行耗时操作,那样会造成界面卡顿,如下就是一个简单的示例: public partial class MainW ...
- Android多线程更新UI的方式
Android下,对于耗时的操作要放到子线程中,要不然会残生ANR,本次我们就来学习一下Android多线程更新UI的方式. 首先我们来认识一下anr: anr:application not rep ...
- 富客户端 wpf, Winform 多线程更新UI控件
前言 在富客户端的app中,如果在主线程中运行一些长时间的任务,那么应用程序的UI就不能正常相应.因为主线程要负责消息循环,相应鼠标等事件还有展现UI. 因此我们可以开启一个线程来格外处理需要长时间的 ...
- WPF多线程UI更新——两种方法
WPF多线程UI更新——两种方法 前言 在WPF中,在使用多线程在后台进行计算限制的异步操作的时候,如果在后台线程中对UI进行了修改,则会出现一个错误:(调用线程无法访问此对象,因为另一个线程拥有该对 ...
- WPF多线程UI更新
前言 在WPF中,在使用多线程在后台进行计算限制的异步操作的时候,如果在后台线程中对UI进行了修改,则会出现一个错误:(调用线程无法访问此对象,因为另一个线程拥有该对象.)这是很常见的一个错误,一不小 ...
- 36.Android之多线程和handle更新UI学习
android经常用到多线程更新UI,今天学习下. 首先布局比较简单: <?xml version="1.0" encoding="utf-8"?> ...
- C# 后台线程更新UI控件
/********************************************************************************* * C# 后台线程更新UI控件 * ...
- C# WinForms跨线程更新 UI
与在Android中一样, 子线程中更新UI被认为是线程不安全的, 会抛出异常. 子线程返回UI线程中更新UI的一个方法为: 1, 捕获应用的UI线程的上下文; 2, 定义线程任务; 3, 定义线程任 ...
- WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)
原文 WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口) WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验.如果希望做不同线程 ...
随机推荐
- go语言从例子开始之Example35.原子计数器
Go 中最主要的状态管理方式是通过通道间的沟通来完成的,我们在工作池的例子中碰到过,但是还是有一些其他的方法来管理状态的.这里我们将看看如何使用 sync/atomic包在多个 Go 协程中进行 原子 ...
- OpenStack虚拟机网络问题
当发现你的OpenStack虚拟机网络有问题,不妨先试一下这16个步骤 1. Security Group全部打开,这是最基本的,但是很多人容易忘记 其实遇到过无数这种场景了,Debug了半天网络 ...
- Sass--调用混合宏
在 Sass 中通过 @mixin 关键词声明了一个混合宏,那么在实际调用中,其匹配了一个关键词“@include”来调用声明好的混合宏.例如在你的样式中定义了一个圆角的混合宏“border-radi ...
- AGC020C Median Sum
高端操作qaq 又双叒叕读错题了= = 然后重新读题发现不会做了 于是瞅了一波题解 我靠要不要这么暴力呜呜呜 直接bitset O(n^3/w)QAQ 就是f[i]表示i是否能被搞出来 然后我们先不看 ...
- 回顾Servlet及SpringMVC
什么是Servlet? Servlet是运行在Web服务器或应用服务器上的程序,它是作为来自Web浏览器或其他HTTP客户端的请求和HTTP服务器上的数据库 或应用程序之间的中间层. servlet架 ...
- 4412 i2c驱动
1.Linux主机驱动和外设驱动分离思想 外设驱动→API→主机驱动→板机逻辑--具体的i2c设备(camera,ts,eeprom等等) 2.主机驱动 根据控制器硬件手册,操作具体的寄存器,产生波形 ...
- 【Flutter学习】之button按钮
一,概述 由于Flutter是跨平台的,所以有适用于Android和iOS的两种风格的组件.一套是Google极力推崇的Material,一套是iOS的Cupertino风格的组件.无论哪种风格,都是 ...
- 【CF1210C】Kamil and Making a Stream(vector,数论,树)
题意:给定一棵n个点带点权的树,i号点的点定义f(i,j)为i到j路径上所有点的gcd,其中i是j的一个祖先,求所有f(i,j)之和mod1e9+7 2<=n<=1e5,0<=a[i ...
- NOIp 图论算法专题总结 (3):网络流 & 二分图 简明讲义
系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 网络流 概念 1 容量网络(capacity network)是一个有向图,图的 ...
- src,href 和rel的区别
src用于替换当前元素,值一般是引用的文件的绝对路径或者相对路径 href 属性的值可以是任何有效文档的相对或绝对URL,包括片段标识符和JavaScript代码段 rel REL属性用于定义链接的文 ...