using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
using System.Windows.Forms;namespace Extension.MyDll
{/// <summary>/// 辅助类:跨线程更新控件/// </summary>public class MyInvokHelper{#region 委托/// <summary>/// 执行控件对象方法的委托/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="methodName">方法名称</param>/// <param name="args">方法的参数列表</param>/// <returns></returns>private delegate object MethodInvoker(Control control, string methodName, params object[] args);/// <summary>/// 获取对象属性值的委托/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <returns></returns>private delegate object PropertyGetInvoker(Control control, object noneControl, string propertyName);/// <summary>/// 设置对象属性值的委托/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <param name="value">属性设置值</param>private delegate void PropertySetInvoker(Control control, object noneControl, string propertyName, object value);#endregion#region 方法/// <summary>/// 获取对象指定名称的属性值/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <returns></returns>private static PropertyInfo GetPropertyInfo(Control control, object noneControl, string propertyName){if ((control != null || noneControl != null) && !string.IsNullOrEmpty(propertyName)){object obj = noneControl != null ? noneControl : control;Type type = obj.GetType();PropertyInfo pi = type.GetProperty(propertyName);   //获取对应名称的属性值,未找到返回nullif (pi == null){//未找到对应名称的属性throw new InvalidOperationException(string.Format("Can't find property {0} in {1}.", propertyName, type.ToString()));}else{//找到对应名称的属性return pi;}}else{throw new ArgumentNullException("Invaild argument.");}}/// <summary>/// 执行控件对象指定名称的方法(InvokeMethod方法仅针对控件,非控件无Invoke方法)/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="methodName">方法名称</param>/// <param name="args">方法的参数列表</param>/// <returns></returns>public static object InvokeMethod(Control control, string methodName, params object[] args){if (control != null && !string.IsNullOrEmpty(methodName)){if (control.InvokeRequired){//从创建控件的线程以外访问控件return control.Invoke(new MethodInvoker(InvokeMethod), new object[] { control, methodName, args });}else{MethodInfo mi = null;bool argsIsNullFlag = true;if (args != null && args.Length > 0){argsIsNullFlag = false;Type[] types = new Type[args.Length];for (int i = 0; i < args.Length; i++){types[i] = args[i] != null ? args[i].GetType() : null;}mi = control.GetType().GetMethod(methodName, types);    //匹配带参方法}else{argsIsNullFlag = true;mi = control.GetType().GetMethod(methodName);           //匹配无参方法}if (mi != null){return mi.Invoke(control, argsIsNullFlag ? null : args);}else{throw new InvalidOperationException("Invalid method.");}}}else{throw new ArgumentNullException("Invalid argument.");}}/// <summary>/// 获取对象指定名称的属性值/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <returns></returns>public static object GetProperty(Control control, object noneControl, string propertyName){if ((control != null || noneControl != null) && !string.IsNullOrEmpty(propertyName)){if (control != null && control.InvokeRequired){return control.Invoke(new PropertyGetInvoker(GetProperty), new object[] { control, noneControl, propertyName });}else{PropertyInfo pi = GetPropertyInfo(control, noneControl, propertyName);object invoke = (noneControl == null) ? control : noneControl;if (pi != null){if (pi.CanRead){return pi.GetValue(invoke);}else{throw new FieldAccessException(string.Format("{0}.{1} is a write-only property.", invoke.GetType().ToString(), propertyName));}}else{return null;}}}else{throw new ArgumentNullException("Invalid argument.");}}/// <summary>/// GetProperty方法的重载,获取控件对象指定名称的属性值/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <returns></returns>public static object GetProperty(Control control, string propertyName){return GetProperty(control, null, propertyName);}/// <summary>/// 设置对象指定名称的属性值/// </summary>/// <param name="control">控件对象的引用</param>/// <param name="noneControl">非控件对象的引用</param>/// <param name="propertyName">属性名称</param>/// <param name="value">属性设置值</param>/// <returns></returns>public static void SetProperty(Control control, object noneControl, string propertyName, object value){if ((control != null || noneControl != null) && !string.IsNullOrEmpty(propertyName)){if (control != null && control.InvokeRequired){control.Invoke(new PropertySetInvoker(SetProperty), new object[] { control, noneControl, propertyName, value });}else{PropertyInfo pi = GetPropertyInfo(control, noneControl, propertyName);object invoke = (noneControl == null) ? control : noneControl;if (pi != null){if (pi.CanWrite){pi.SetValue(invoke, value);}else{throw new FieldAccessException(string.Format("{0}.{1} is a read-only property.", invoke.GetType().ToString(), propertyName));}}}}else{throw new ArgumentNullException("Invalid argument.");}}/// <summary>/// SetProperty方法的重载,设置控件对象指定名称的属性值/// </summary>/// <param name="control"></param>/// <param name="propertyName"></param>/// <param name="value"></param>public static void SetProperty(Control control, string propertyName, object value){SetProperty(control, null, propertyName, value);}#endregion}
}

经验证过的跨线程更新辅助类MyInvokeHelper相关推荐

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

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

  2. 简短总结一下C#里跨线程更新UI

    简短总结一下C#里跨线程更新UI 摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问 ...

  3. 简短总结一下C#里跨线程更新UI(转)

    摘自: http://my.oschina.net/sdqxcxh/blog/53707 跨线程更新UI是写多线程程序尤其是通信类的程序经常遇到的问题,这里面主要的问题是冲突,比如数据线程想要更新UI ...

  4. C#跨线程更新控件(UI)使用delegate方式

    C#跨线程更新(获取)控件(UI)使用delegate方式 在做界面开发的时候经常用到多线程,并且要在work线程中对控件或者界面进行操作,下面给出几种常用的操作方法 使用匿名委托到主线程中进行UI异 ...

  5. AndroidStudio_Android中使用Handler实现非阻塞线程间通讯_跨线程更新UI_耗时处理完成后主动通知更新UI_在同一个activity用---Android原生开发工作笔记219

    其实也是很简单的,比如,我们要是在android中去访问,http请求服务器的话,那么这个时候,UI线程不会一直等着,你访问完成,再去更新UI,因为这样 会导致看起来卡顿. 这个时候可以这样: 例如我 ...

  6. [转]C#利用委托跨线程更新UI数据

    在使用C#的过程中,难免会用到多线程,而用多线程之后,线程如何与界面交互则是一个非常头疼的问题.其实不仅仅是界面,一般情况下,我们往往需要获得线程的一些信息来确定线程的状态.比较好的方式是用委托实现, ...

  7. 同步上下文(SynchronizationContext) 和 C#中跨线程更新UI的方法总结

    同步上下文(SynchronizationContext) 和 C#中跨线程更新UI的方法总结 在C#编程环境中,不允许在工作线程中直接对主线程(UI线程)中的控件进行更新操作.因此,稍微复杂一点的程 ...

  8. C#-WinForm跨线程修改UI界面

    背景 在我做WinForm开发的过程中,经常会遇到耗时操作或阻塞操作.他们会引发软件的卡顿甚至假死,严重影响软件的使用.因此,这类耗时或阻塞的操作一般都会使用异步的方式去执行,不影响主线程(UI线程) ...

  9. 跨线程操作无效:从创建该线程的线程以外的线程访问控件

    我有一个场景. (Windows窗体,C#.. NET) 有一个主窗体可以承载一些用户控件. 用户控件执行一些繁重的数据操作,因此,如果我直接调用UserControl_Load方法,则UI在加载方法 ...

最新文章

  1. OA办公系统使用之:Tomcat与mysql的几个常见问题
  2. Azure运维系列 3:善用Azure捕获功能事半功倍
  3. python第三天习题
  4. 15个问题告诉你如何使用Java泛型
  5. 创新元旦新年PSD分层海报,新气象开启!
  6. springsecurity oauth2_跟OAuth2杠上了,老师,我要学全套的!
  7. OpenGL基础42:实例化
  8. java script 视频教程_智能社JS全套视频教程+高清入门javascript下载
  9. 通达信版弘历软件指标_弘历指标源码:弘历软件主要功能是什么?选股精不精准?...
  10. 卷积码编码和译码c语言,卷积码编码和译码.doc
  11. SQL注入环境搭建及多种注入类型测试实验
  12. 【11-13】A股主要指数的市盈率(PE)估值高度
  13. 《ZLToolKit源码学习笔记》(17)网络模块之基础接口封装类SockUtil
  14. 软件开发模型优点缺点
  15. 跨境物流主要流程是什么样?
  16. scrapy框架入门第一天笔记记录
  17. 介绍下微信刷票被禁了怎么办及微信拉票怎么人工买票的方法
  18. 【Numpy】用Python求解数独
  19. 关于InnoDB存储引擎 text blob 大字段的存储和优化--转载
  20. htc one m7刷Linux,HTC One M7 刷机图文教程 一键刷Recovery教程

热门文章

  1. ALIN10129-自查方案
  2. 考研计算机专业课统考吗,【计算机考研】你了解计算机统考408吗?
  3. 局域网抢答器_基于童芯派的抢答器V1.0
  4. audino python_用 Python 实现 PowerDesigner 数据模型文件的处理
  5. Java编程中的基本概念
  6. 中职 计算机老师 教cad,教师博客应用于职校计算机CAD教学探究.doc
  7. android怎么根据标题解析json,如何在android中解析没有json对象标题的json数组?
  8. HDU 1176 免费馅饼 (动态规划、另类数塔)
  9. 《鸟哥的Linux私房菜--基础篇》学习
  10. web语义化与h5新增标签