转自原文 多线程环境下的UI异步操作

解决VS中,线程间不可互操作的问题,一揽子解决方案:

一、首先,定义一个类:SetControlProperty

using System.Reflection;
using System;
using System.Windows.Forms;
namespace Ways.Utils
{
    class SetControlProperty
    {
        delegate void SetValueDelegate(Object obj, Object val, Object[] index);
        public SetControlProperty(Control ctrl, String propName, Object val)
        {
            PropertyInfo propInfo = ctrl.GetType().GetProperty(propName);
            Delegate dgtSetValue = new SetValueDelegate(propInfo.SetValue);
            ctrl.Invoke(dgtSetValue, new Object[3] { ctrl, val, null });
        }
    }
}

二、在要操作Form中调用

本例中,此调用是由一通讯事件引发的:

void testcommand_EndStatusEvent(object sender, EventArgs e)
{
    new SetControlProperty(label4, "Text", "END");
    new SetControlProperty(button1, "Enabled", true);
} 

三、 最简化,但却不安全的方案

Control.CheckForIllegalCrossThreadCalls = false;

试过了,在.net compact framework中,不可用!

四、.NETCF中的解决方案,来源:.NET Compact Framework 多线程环境下的UI异步刷新

在进行WinCe或者Windows Mobile开发中,通常需要把一些任务提交给工作线程(Worker Thread)完成,当worker thread 线程发生状态变更的时候需要通知UI进程刷新UI,比如一个网络连接程序,Worker Thread线程负责管理WiFi,GPRS或者3G等连接,当连接状态发生改变时候,Worker Thread把更新状态通知UI Thread,而UI Thread更新UI通知用户。

这里常常有个疑问,为什么Worker Thread不直接更新UI,这样更简单直接和明了。但是UI刷新不是线程安全(Thread Safe)的,所以Worker Thread直接更新UI会抛出"cross-thread operation not valid"异常。所以需要Thread Safe的通知方法,下面演示更新短语(Message)的方法如下:
Worker Thread Class

class ConnectionMgr
{
    //Delegate for Message
    public delegate void MessageEventHandler(string msg);
    public event MessageEventHandler MessageEvent;
    //the delegate of Message event
    private void MessageHandler(string msg)
    {
        MessageEventHandler messageEvent = MessageEvent;
        if (messageEvent != null)
        {
            messageEvent(msg);
        }
    }
    private void ConnectHandler()
    {
        MessageHandler("Connected");
    }
    private void DisconnectHandler()
    {
        MessageHandler("Disconnected");
    }
} 

在Worker Thread定义delegate和event供UI Thread注册。当状态发生改变是调用该delegate。

UI Thread

public partial class Form1 : Form
{
    public Form1()
    {
        //register the connect event
        ConnectionMgr.Instance.MessageEvent += MessageEvent;
    }
    private void MessageEvent(string msg)
    {
        SafeWinFormsThreadDelegate d = new SafeWinFormsThreadDelegate(ShowMessage);
        Invoke(d, new object[] { msg} );
    }
    public delegate void SafeWinFormsThreadDelegate(string msg);
    private void ShowMessage(string msg)
    {
        eventText.Text = msg;
    }
} 

UI Thread通过delegate订阅连接事件,当连接状态发生改变的时候,Worker Thread异步调用void MessageEvent(string msg)。这里调用Invoke方法来进行线程安全的调用。调用参数使用Object[]来传递,因此程序可以传递任何信息,UI可以呈现任何信息只要Worker Thread能提供。

多线程环境下的UI异步操作的更多相关文章

  1. Asp.Net在多线程环境下的状态存储问题

    在应用开发中,我们经常需要设置一些上下文(Context)信息,这些上下文信息一般基于当前的会话(Session),比如当前登录用户的个人信息:或者基于当前方法调用栈,比如在同一个调用中涉及的多个层次 ...

  2. C#多线程环境下调用 HttpWebRequest 并发连接限制

    C#多线程环境下调用 HttpWebRequest 并发连接限制 .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 win ...

  3. C++多线程环境下的构造函数

    多线程的环境里,我们总不可避免要使用锁.于是一个常见的场景就是: class ObjectWithLock { private: std::mutex mtx_; SomeResType shared ...

  4. SQLite在多线程环境下的应用

    文一 SQLite的FAQ里面已经专门说明,先贴出来.供以后像我目前的入门者学习. (7) 多个应用程序或者同一个应用程序的多个例程能同时存取同一个数据库文件吗? 多进程可以同时打开同一个数据库,也可 ...

  5. 多线程环境下非安全Dictionary引起的“已添加了具有相同键的项”问题

    问题: 代码是在多线程环境下,做了简单的Key是否存的判断, 测试代码如下: public class Program { static Dictionary<string, Logger> ...

  6. HttpClient在多线程环境下踩坑总结

    问题现场 在多线程环境下使用HttpClient组件对某个HTTP服务发起请求,运行一段时间之后发现客户端主机CPU利用率呈现出下降趋势,而不是一个稳定的状态. 而且,从程序日志中判断有线程处于han ...

  7. 单例模式在多线程环境下的lazy模式为什么要加两个if(instance==null)

    刚才在看阿寻的博客”C#设计模式学习笔记-单例模式“时,发现了评论里有几个人在问单例模式在多线程环境下为什么lazy模式要加两个if进行判断,评论中的一个哥们剑过不留痕,给他们写了一个demo来告诉他 ...

  8. 一个由单例模式在多线程环境下引发的 bug

    问题症状 HTTP 日志系统,老是出现日志信息覆盖的情况.比如同时调用 A 接口和 B 接口,B 接口请求响应信息变成了 A 接口请求响应相关信息.这个问题在并发量大的情况下越来越严重. 问题初步分析 ...

  9. 你是否听说过 HashMap 在多线程环境下操作可能会导致程序死循环?

    作者:炸鸡可乐 原文出处:www.pzblog.cn 一.问题描述 经常有些面试官会问,是否了解过 HashMap 在多线程环境下使用时可能会发生死循环,导致服务器 cpu 100% 的线上故障? 关 ...

随机推荐

  1. 全球常用NTP服务器地址及IP列表ntpdate

    pool.ntp.org是一组授时服务器虚拟集群,在全球有3000多台服务器,只需要这样写就行了,具体哪台服务器提供服务无需关心. time.windows.com   微软 asia.pool.nt ...

  2. pat甲级 1152 Google Recruitment (20 分)

    In July 2004, Google posted on a giant billboard along Highway 101 in Silicon Valley (shown in the p ...

  3. Working out

    Summer is coming! It's time for Iahub and Iahubina to work out, as they both want to look hot at the ...

  4. RF自定义系统关键字

    如果您准备学习Python,船长在这里给大家推荐几个学习Python的好地方:   1.廖雪峰官网 http://www.liaoxuefeng.com/wiki/001374738125095c95 ...

  5. c#开发的程序安装时动态指定windows服务名称

    转自:http://www.jb51.net/article/30549.htm 前段时间由于项目的需求,要在Windows里把同样的组件制作成多个不同名称的服务,这些服务完成类似的功能,仅需要修改业 ...

  6. php mysql 字符集(三) (转)

    http://bbs.csdn.net/topics/390097514 gbk页面插入数据到utf8表,然后取出到gbk页面 首先, 这个set names x等价于SET character_se ...

  7. nginx虚拟机的配置

    user nginx nginx;worker_processes 1;pid /data/var/run/nginx/nginx.pid;worker_rlimit_nofile 51200; ev ...

  8. linux网络编程、系统编程

    http://blog.csdn.net/lianghe_work/article/category/2871247

  9. struts2学习(11)struts2验证框架1.验证简介、内置验证

    一.Struts2验证简介: 二.struts2内置验证: 下面例子,需求是:为用户注册进行验证: com.cy.model.User.java: package com.cy.model; publ ...

  10. 【转】jMeter入门实例

    人们对从认识事物都有一个具体到抽象的过程,学习Jmeter也不例外,通过一个实例来进行学习,一方面可以让初学者有所见即所得的信心,另一方面,其实也是在初学者心中留下了对这事物的一个朦胧的印象,这在以后 ...