那么该如何解决这一问题呢?通常的做法是把耗时的函数放在线程池执行,然后切回主线程更新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的一个解决途径的更多相关文章

  1. 拒绝卡顿——在WPF中使用多线程更新UI

    原文:拒绝卡顿--在WPF中使用多线程更新UI 有经验的程序员们都知道:不能在UI线程上进行耗时操作,那样会造成界面卡顿,如下就是一个简单的示例: public partial class MainW ...

  2. Android多线程更新UI的方式

    Android下,对于耗时的操作要放到子线程中,要不然会残生ANR,本次我们就来学习一下Android多线程更新UI的方式. 首先我们来认识一下anr: anr:application not rep ...

  3. 富客户端 wpf, Winform 多线程更新UI控件

    前言 在富客户端的app中,如果在主线程中运行一些长时间的任务,那么应用程序的UI就不能正常相应.因为主线程要负责消息循环,相应鼠标等事件还有展现UI. 因此我们可以开启一个线程来格外处理需要长时间的 ...

  4. WPF多线程UI更新——两种方法

    WPF多线程UI更新——两种方法 前言 在WPF中,在使用多线程在后台进行计算限制的异步操作的时候,如果在后台线程中对UI进行了修改,则会出现一个错误:(调用线程无法访问此对象,因为另一个线程拥有该对 ...

  5. WPF多线程UI更新

    前言 在WPF中,在使用多线程在后台进行计算限制的异步操作的时候,如果在后台线程中对UI进行了修改,则会出现一个错误:(调用线程无法访问此对象,因为另一个线程拥有该对象.)这是很常见的一个错误,一不小 ...

  6. 36.Android之多线程和handle更新UI学习

    android经常用到多线程更新UI,今天学习下. 首先布局比较简单: <?xml version="1.0" encoding="utf-8"?> ...

  7. C# 后台线程更新UI控件

    /********************************************************************************* * C# 后台线程更新UI控件 * ...

  8. C# WinForms跨线程更新 UI

    与在Android中一样, 子线程中更新UI被认为是线程不安全的, 会抛出异常. 子线程返回UI线程中更新UI的一个方法为: 1, 捕获应用的UI线程的上下文; 2, 定义线程任务; 3, 定义线程任 ...

  9. WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口)

    原文 WPF 同一窗口内的多线程/多进程 UI(使用 SetParent 嵌入另一个窗口) WPF 的 UI 逻辑只在同一个线程中,这是学习 WPF 开发中大家几乎都会学习到的经验.如果希望做不同线程 ...

随机推荐

  1. 三 Bash Shell 结构

    Bash Shell 程序结构主要有 : 变量设定  内置命令 Shell 语法结构 函数 其他命令行程序构成 例子: [root@localhost ~]# vim test.sh #!/bin/b ...

  2. Cent OS 7 VNC 安装

    关闭防火墙 关闭selinux 挂载光盘到本地 #yum install tigervnc-server -y #cp /lib/systemd/system/vncserver@.service / ...

  3. linux的iptables设置---防火墙

    1.首先介绍一下指令和相关配置文件 启动指令:service iptables start 重启指令:service iptables restart 关闭指令:service iptables st ...

  4. linux内核启动过程

    作者:严哲璟 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 通过qemu以 ...

  5. Django学习笔记-修改Django的默认的数据库

    1.修改设置settings中的配置 DATABASES = { 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os ...

  6. elasticsearch删除

    1.根据id删除 2.根据查询条件删除

  7. JAVA 利用 jmc或jvisualvm 监控 本地或者远程JVM

    本地检测之间到$JAVA_HOME/bin 下的目录点击jmc 或者jvisualvm,然后选择你要监控的app 可是一般我们生产环境项目都是部署在远程,这个时候想要监控怎么办 1.监控tomcat ...

  8. 【SPOJ1811】Longest Common Substring(后缀自动机)

    题意:给定两个仅含小写字母的字符串,求他们最长公共子串的长度 n<=250000 思路: #include<bits/stdc++.h> using namespace std; t ...

  9. 汉诺塔IX

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=76447#problem/E 汉诺塔IX Time Limit:1000MS     Me ...

  10. 全国5A级旅游景区已达250家

    至目前,全国5A级旅游景区已达250家,快来数数你去过多少? 全国5A级旅游景区 西藏(+) 拉萨市大昭寺.拉萨布达拉宫景区.日喀则扎什伦布寺景区.林芝巴松措景区 新增1:日喀则扎什伦布寺景区 扎什伦 ...