实现功能:

后台线程改变窗体控件(flowLayoutPanel1)的状态。

利用 this.flowLayoutPanel1.InvokeRequired == false,可以知道是主线程调用的自己控件,还是其他线程调用。

如果其他线程调用就使用DisplayDelegate代理。

窗体初期化时要加,允许线程间调用:

CheckForIllegalCrossThreadCalls = false;

窗体加载时启动一个匿名线程threadStatus,循环监视clientList列表。如果列表中的数值改变则改变窗体控件的状态。

namespace XXXX
{
public partial class Frm_Manage : Form
{
// 客户端状态列表
Dictionary<string, SocketClientInfo> clientList;
// 线程间调用代理
private delegate void DisplayDelegate(string clientIp, string clientNum, string status);
// 心跳线程
public Thread threadStatus { set; get; } public Frm_Manage()
{
// 允许线程间调用
CheckForIllegalCrossThreadCalls = false;
InitializeComponent();
} private void Frm_Manage_Load(object sender, EventArgs e)
{
SocketServer Socketservice = SocketServer.GetInstance();
clientList = Socketservice.GetClientDictionary(); threadStatus = new Thread(() =>
{
while (true)
{
foreach (SocketClientInfo item in clientList.Values)
{
bool existFlg = false;
foreach (Control subPan in this.flowLayoutPanel1.Controls)
{
if (subPan.Name == item.clientIp)
{
// 存在该终端,改变显示状态
subPan.BackColor = GetBackColor(item.clientStatus);
existFlg = true;
break;
}
}
if (!existFlg)
{
// 不存在该终端,添加新控件
AddDisplay(item.clientIp, item.clientNum, item.clientStatus);
}
}
this.flowLayoutPanel1.Refresh(); Thread.Sleep( * time);// 间隔1秒刷新页面
}
});
threadStatus.Start();
} private Color GetBackColor(string status)
{
if (status == "")
{
return Color.Silver;// 灰色
}
else if (status == "")
{
return Color.LawnGreen;// 绿色
}
else if (status == "")
{
return Color.Gold;// 黄色
}
else if (status == "")
{
return Color.Orange;// 橙色
}
else if (status == "")
{
return Color.Red;// 红色
}
else
{
return Color.Silver;// 灰色
}
} private void AddDisplay(string clientIp, string clientNum, string status)
{
try
{
//如果调用该函数的线程和控件flowLayoutPanel1位于同一个线程内
if (this.flowLayoutPanel1.InvokeRequired == false)
{
//直接将内容添加到窗体的控件上
Panel pal = new Panel();
pal.Name = clientIp;
pal.Width = DisStatusW_PX;
pal.Height = DisStatusH_PX;
pal.BackColor = GetBackColor(status);
pal.Controls.Add(pic); this.flowLayoutPanel1.Controls.Add(pal);
}
//如果调用该函数的线程和控件flowLayoutPanel1不在同一个线程
else
{
//通过使用Invoke的方法,让子线程告诉窗体线程来完成相应的控件操作
DisplayDelegate disp = new DisplayDelegate(AddDisplay); //使用控件flowLayoutPanel1的Invoke方法执行Display代理(其类型是DisplayDelegate)
this.flowLayoutPanel1.Invoke(disp, clientIp, clientNum, status);
}
}
catch (Exception e)
{
LogHelper.WriteError(typeof(Frm_Manage), e);
}
}
}
}

C# 使用代理实现线程间调用的更多相关文章

  1. 线程间通信 GET POST

    线程间通信有三种方法:NSThread   GCD  NSOperation       进程:操作系统里面每一个app就是一个进程. 一个进程里面可以包含多个线程,并且我们每一个app里面有且仅有一 ...

  2. 【问题解决】线程间操作无效:从不是创建控件“textBox1”的线程访问它

    背景 通过一个辅助线程计算出的一个值赋给textBox1.text: 解决办法 1.直接在窗体的构造函数中添加: System.Windows.Forms.Control.CheckForIllega ...

  3. 关于“线程间操作无效: 从不是创建控件’textBox1‘的线程访问它”异常的解决方法

    线程间操作无效: 从不是创建控件“textBox1”的线程访问它 背景:通过一个辅助线程计算出的一个值赋给textBox1.text;解决办法:1.直接在窗体的构造函数中加:System.Window ...

  4. 从.NET 1.1 升级到.NET 4.0 遇到 线程间操作无效: 从不是创建控件 [XX] 的线程访问它.

    有两种方式解决 1.在窗体构造函数中写Control.CheckForIllegalCrossThreadCalls =false;2.使用Invoke等委托函数 问题原因是 .NET2.0 以后拒绝 ...

  5. (转载)Java里快如闪电的线程间通讯

    转自(http://www.infoq.com/cn/articles/High-Performance-Java-Inter-Thread-Communications) 这个故事源自一个很简单的想 ...

  6. Java中快如闪电的线程间通讯

    这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...

  7. iOS开发之线程间的MachPort通信与子线程中的Notification转发

    如题,今天的博客我们就来记录一下iOS开发中使用MachPort来实现线程间的通信,然后使用该知识点来转发子线程中所发出的Notification.简单的说,MachPort的工作方式其实是将NSMa ...

  8. wusir 线程间操作无效: 从不是创建控件“”的线程访问它 解决办法

    利用FileSystemWatcher设计一个文件监控系统时,如果一个文件被修改或者新建,则文件修改事件会被多次触发而产生多条信息.为了将一个文件被修改一次而产生的多条信息归结为一条,在设计中新开了一 ...

  9. Java 里快如闪电的线程间通讯

    这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...

随机推荐

  1. [Qt2D绘图]-04绘制文字&&绘制路径

    注:学习自<Qt Creator 快速入门>第三版.   文档中的示例参考 Qt Example推荐:Painter Paths Example和Vector Deformation   ...

  2. Linux下diff工具

    目录 CentOS 7为例 Meld DiffMerge KDiff3 Kompare CentOS 7为例 Meld Installation 官网 $ sudo yum install meld; ...

  3. void operator()()的功能

    在学习多线程的时候看到这样的一段代码,为什么要重载()呢?真有这个必要吗? #include <iostream> #include <thread> class Counte ...

  4. JavaScript以万或亿为单位显示,并保留两位小数或取整

    //单位:万 n = 814308678.00; n = Math.floor((n /10000) * 100) / 100; //保留小数点两位 //n = parseInt((n /10000) ...

  5. STL源码剖析:仿函数

    仿函数就是函数对象 函数对象: 重载了operator()的类对象 使用起来和普通函数一致,所以称为函数对象或是仿函数 STL中对于仿函数的参数进行了特殊处理,定义了两个特殊类,类里面只有类型定义 一 ...

  6. abp vnext 开发快速入门 3 实现权限控制

    上篇讲了abp vnext 实现了简单的增加操作的例子.删除更新查询基本类似,这里就不讲了,接下来说下如何实现角色权限控制. 再说之前,先说下如果想更加透彻的理解abp vnext的权限控制,最好是先 ...

  7. 我把JVM的类加载器整理了一下

    前言 ​ 之前去面试的时候面试官问了我关于关于JVM性能调优的问题,由于自己之前公司的项目里自己没有接触到JVM性能调优的相关问题(感觉这些都是公司架构师考虑的问题),所有面试官问的时候自己一脸懵逼, ...

  8. python-闭包和装饰器-02-装饰器(decorator)

    装饰器(decorator) 理解了上一章的闭包之后,装饰器就是闭包的一种应用,只是外部函数的参数传入的不是普通的变量类型,而是传入一个函数名.装饰器一般用于:不修改被装饰函数(即外部函数传入的参数) ...

  9. fgdsafhak

  10. pandas之数值计算与统计

    数值计算与统计 对于DataFrame来说,求和.最大.最小.平均等统计方法,默认是按列进行统计,即axis = 0,如果添加参数axis = 1则会按照行进行统计. 如果存在空值,在统计时默认会忽略 ...