博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程环境下的UI异步操作
阅读量:6702 次
发布时间:2019-06-25

本文共 2345 字,大约阅读时间需要 7 分钟。

转自原文

解决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中的解决方案,来源:

在进行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能提供。

 

转载地址:http://fagoo.baihongyu.com/

你可能感兴趣的文章
new FormData() - FormData对象的作用及用法
查看>>
Out of memory: Kill process 内存不足
查看>>
linux 基础(一)
查看>>
ejb-jar.xml
查看>>
最新杭州地铁开通时间表
查看>>
关闭shift中英文切换 英文代码/中文注释随意切换着写。
查看>>
距离北京奥运还有359天,发布WPF版本的北京2008标志(下)
查看>>
命令模式
查看>>
如何自定义长连接策略
查看>>
平衡二叉树与自平衡二叉树(红黑树)的区别
查看>>
读取JPG图片的Exif属性(一) - Exif信息简介
查看>>
【译文】追求生产极简主义
查看>>
FTP服务器原理(转)
查看>>
精选30道Java笔试题解答
查看>>
特殊符号 UNICODE编码
查看>>
C#图解教程 第八章 表达式和运算符
查看>>
解决NavicatPremium导入CSV文件中文乱码的问题
查看>>
Python基础:语法基础(3)
查看>>
单元测试利器 JUnit 4
查看>>
杭电2097
查看>>