一个解决在非UI线程中访问UI 异常的小方法
写 WPF 的童鞋可能都会碰到 在非UI线程中访问 UI 异常的问题。这是为了防止数据不一致做的安全限制。
子线程中更新UI还要交给主线程更新,引用满天飞,实在是麻烦。
接下来,我们推出一个可以称之为框架的解决方案(拍砖的时候轻点)。
一:解决判断当前线程是主线成的问题
在 C# 中 微软好像没有给出直接判断当前线程是否是主线程的方案,至少我是没找到。
如果您有更好的解决方案请留言哦!!!!
/// <summary>
/// Lyx 线程框架 类
/// </summary>
public class LyxThreadFrame
{
/// <summary>
/// 主线程 签名
/// </summary>
public const string MainThreadIdiograph = "Main Thread"; /// <summary>
/// 初始化 线程检测框架
/// <para>请在UI(主)线程下初始化</para>
/// </summary>
public static void Init()
{
var thread = System.Threading.Thread.CurrentThread;
thread.Name = MainThreadIdiograph;
}
}
我的解决方案是,在程序启动的时候先给主线程命名
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
LyxThreadFrame.Init();
base.OnStartup(e);
}
}
我会重写 Application 类的 OnStartup() 方法,在这个方法中去初始化当前框架
OnStartup() WPF 程序启动的入口点,主窗口的创建就是在这里了。
/// <summary>
/// 线程 扩展类
/// </summary>
public static class ThreadExtension
{
/// <summary>
/// 当前线程是否是主线程
/// </summary>
public static bool IsMainThread(this Thread thread)
{
if (thread == null)
{
throw new ArgumentNullException("thread");
}
if (thread.Name == null)
{
return false;
}
return thread.Name.Equals(LyxThreadFrame.MainThreadIdiograph);
}
}
扩展线程类,用于判断当前方法是否是主线程,判断下指定线程是否是哥当初赏赐了名字的那个线程。
好了,到这里就能判断当前线程是否是主线程了。
二:让你的UI 访问代码在UI(主)线程下执行
/// <summary>
/// 委托 扩展类
/// </summary>
public static class DelegateExtension
{
/// <summary>
/// 在UI(主)线程中执行
/// </summary>
public static object SafetyInvoke(this Delegate dele, params object[] param)
{
var thread = System.Threading.Thread.CurrentThread;
if (thread.IsMainThread())
{
return dele.DynamicInvoke(param);
}
else
{
return Application.Current.Dispatcher.Invoke(dele, param);
}
}
}
在这里我们扩展了 Delegate 这里有个 Application 类,我们程序中的 App 就是继承了这个。它是程序的入口点。
这样我们就创建了一个安全的 访问UI的环境。
示例:
public void Hello()
{
var action = new Action(() =>
{
//更新UI
});
action.SafetyInvoke();
}
一个解决在非UI线程中访问UI 异常的小方法的更多相关文章
- UWP 在非UI线程中更新UI
大家都知道,不可以在 其他线程访问 UI 线程,访问 UI 线程包括给 依赖属性设置值.读取依赖属性.调用方法(如果方法里面修改了依赖属性)等.一旦访问UI线程,那么就会报错,为了解决这个问题,需要使 ...
- Android开之在非UI线程中更新UI
当在非UI线程中更新UI(程序界面)时会出现例如以下图所看到的的异常: 那怎样才干在非UI线程中更细UI呢? 方法有非常多种.在这里主要介绍三种: 第一种:调用主线程mHandler的post(Run ...
- 为什么在非UI线程中操作UI的改变失不安全的
因为你如果允许在非UI线程更新操作UI的东西,那我再另一个非UI线程也可以更新这个Ui的东西 这样就会有冲突,比如你的线程刚好跑到修改UI这里,我的另一个UI也有可能跑到这里,所以这样导致线程不安全. ...
- Android在非UI线程中更新UI的方法
1.使用Thread+Handler实现非UI线程更新UI界面 在UI Thread中创建Handler.用sendMessage(message)或者obtainMessage(result, ob ...
- 在非UI线程中更改UI(Delphi使用隐藏窗口来处理,QT使用信号槽)
在Delphi里我记得是使用TThread.Synchronize(TThreadMethod),原理是利用了一个隐藏窗口来处理. 在QT Debug模式一下,碰到了同样的问题,显示错误: canno ...
- android在其他线程中访问UI线程的方法
1.Activity.runOnUiThread( Runnable ) 2.View.post( Runnable ) 3.View.postDelayed( Runnable, long ) 4. ...
- android4.0以上访问网络不能在主线程中进行以及在线程中操作UI的解决方法
MONO 调用一个线程操作UI 然后报Only the original thread that created a view hierarchy can touch its views.错误 goo ...
- Android 高级UI设计笔记17:Android在非UI线程中显示Toast
1. 子线程的Toast怎么显示不出来? 因为Toast在创建的时候会依赖于一个Handler,并且一个Handler是需要有一个Looper才能够创建,而普通的线程是不会自动去创建一个Looper对 ...
- Android中高效的显示图片之二——在非UI线程中处理图片
在“加载大图”文章中提到的BitmapFactory.decode*方法,如果源数据是在磁盘.网络或其它任何不是在内存中的位置,那么它都不应该在UI线程中执行.因为它的加载时间不可预测且依赖于一系列因 ...
随机推荐
- ANR异常
ANR异常 一.简介 解决方法:别在主线程中写非常耗时的操作 二.代码实例 点击之后,不停点击,乱点 出现anr异常 代码 /anr/src/anr/MainActivity.java package ...
- Linux运维第二天:安装虚拟机软件及RHEL7.2 64位系统
第一步:安装虚拟机 一路默认就行啦(还是要改下安装路径,嘿嘿) 第二步:安装RHEL7.2 64位系统 1.新建一个虚拟机 典型和自定义随便选(最后都可以调的) 一般大婶都喜欢选自定义(自己可以设置的 ...
- webstrom提示不见了
今天做项目时候,不知道怎么搞的我的神编辑器webstrom没有了代码提示!!! 重启软件.重启电脑甚至卸载重装都不行,研究了半天终于知道问题出在了哪: 后来我发现在Webstorm的菜单[File]里 ...
- poj-2342-简单树形dp
Anniversary party Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10388 Accepted: 594 ...
- IOS-UISearchBar
UISearchBar控件 最近用到搜索功能.于是,经过不断的研究,终于,有点懂了. 那就来总结一下吧,好记性不如烂笔头! 搜索,无疑可以使用UISearchBar控件! 那就先了解一下UISea ...
- main函数的参数:argc和argv
程序一般是从main函数开始执行的,main函数标准格式: int main(int argc,char **argv) 其中argc是来自shell(或CMD)的参数的个数,argv是char型的二 ...
- 网页重构中区分IE6、IE7、IE8及标准浏览器的最佳方法
由于万恶的IE6和IE7,我们在页面重构时不免要对其进行各种bug修复及差异化处理.在标准浏览器中可实现的效果在IE里却有各种离奇问题,例如IE6.IE7不能良好应对的inline-block和.cl ...
- Oracle 对比两张表不一样 的数据
闲来无事,更一片博客,前几天有一个项目中有一个需求,用户通过excel导入数据,由于是通用的导入,所以导入的列的类型都为varchar,所以需要建一张中间表,使其列都为varchar类型,然后通过存储 ...
- 字符串-----KMP竟然是18禁
今天学了一下午字符串,讲到结束也没讲KMP.有人问老师为什么不讲,老师来一句:字符串noip不考,而且还是18禁,自然不讲.[手动滑稽] 所以我也不讲.[微笑] 1.表达式树 表示3+5*8 最后计算 ...
- Python变量、字符练习1
1.判断一个变量是否合法:(变量由字母.数字下划线组成:且开头不是数字) while True: s = raw_input("please input values:") if ...