C# 使用代理实现线程间调用
实现功能:
后台线程改变窗体控件(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# 使用代理实现线程间调用的更多相关文章
- 线程间通信 GET POST
线程间通信有三种方法:NSThread GCD NSOperation 进程:操作系统里面每一个app就是一个进程. 一个进程里面可以包含多个线程,并且我们每一个app里面有且仅有一 ...
- 【问题解决】线程间操作无效:从不是创建控件“textBox1”的线程访问它
背景 通过一个辅助线程计算出的一个值赋给textBox1.text: 解决办法 1.直接在窗体的构造函数中添加: System.Windows.Forms.Control.CheckForIllega ...
- 关于“线程间操作无效: 从不是创建控件’textBox1‘的线程访问它”异常的解决方法
线程间操作无效: 从不是创建控件“textBox1”的线程访问它 背景:通过一个辅助线程计算出的一个值赋给textBox1.text;解决办法:1.直接在窗体的构造函数中加:System.Window ...
- 从.NET 1.1 升级到.NET 4.0 遇到 线程间操作无效: 从不是创建控件 [XX] 的线程访问它.
有两种方式解决 1.在窗体构造函数中写Control.CheckForIllegalCrossThreadCalls =false;2.使用Invoke等委托函数 问题原因是 .NET2.0 以后拒绝 ...
- (转载)Java里快如闪电的线程间通讯
转自(http://www.infoq.com/cn/articles/High-Performance-Java-Inter-Thread-Communications) 这个故事源自一个很简单的想 ...
- Java中快如闪电的线程间通讯
这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...
- iOS开发之线程间的MachPort通信与子线程中的Notification转发
如题,今天的博客我们就来记录一下iOS开发中使用MachPort来实现线程间的通信,然后使用该知识点来转发子线程中所发出的Notification.简单的说,MachPort的工作方式其实是将NSMa ...
- wusir 线程间操作无效: 从不是创建控件“”的线程访问它 解决办法
利用FileSystemWatcher设计一个文件监控系统时,如果一个文件被修改或者新建,则文件修改事件会被多次触发而产生多条信息.为了将一个文件被修改一次而产生的多条信息归结为一条,在设计中新开了一 ...
- Java 里快如闪电的线程间通讯
这个故事源自一个很简单的想法:创建一个对开发人员友好的.简单轻量的线程间通讯框架,完全不用锁.同步器.信号量.等待和通知,在Java里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...
随机推荐
- OSCP Learning Notes - Enumeration(3)
SMB Enumeration 1. Set the smb configurations. locate smb.conf vim /etc/samba/smb.conf Insert the gl ...
- 因为mac不支持移动硬盘的NTFS格式,mac电脑无法写入移动硬盘的终极解决办法
相信很多实用mac的同学,都有磁盘容量问题,所以才使用移动硬盘 当移动硬盘在windows电脑上使用过之后,会被格式化为NTFS格式 而mac电脑不支持NTFS格式 这里有两种方法 第一种是把移动硬盘 ...
- Kubernetes的10个基本事实!你知道几个?k8s与Docker又有何不同?
无论您是Kubernetes的新手还是只是想获得更多知识,这篇文章都会帮到您! Kubernetes是一个增长的趋势.近年来,K8s技术经历了从小型开源Google项目到Cloud Native Co ...
- Redis的字符串底层是啥?为了速度和安全做了啥?
面试场景 面试官:Redis有哪些数据类型? 我:String,List,set,zset,hash 面试官:没了? 我:哦哦哦,还有HyperLogLog,bitMap,GeoHash,BloomF ...
- 设计模式:memento模式
目的:在不破坏系统封装性的前提下,记录系统每一步的状态,可以做到状态回退和前进 方法: 定义一个数据类,保存所有相关数据 定义一个管理类,提供保存和恢复的接口 具体操作类调用管理类的保存和恢复接口 例 ...
- windows如何解决Error: Registry key 'Software\JavaSoft\Java Runtime Environment'\CurrentVersion'
问题再现与解读 首次,使用 java 命令+任意参数 都会报这个错误,最典型的就是java -version 解读一下这个报错信息,注册表路径 Software\JavaSoft\Java Runti ...
- grpc 之 word2pdf使用
做一个word转pdf的服务,采用grpc,使用libreoffice命令. 1.构建libreoffice镜像 FROM python:3.6 ENV TZ=Asia/Shanghai RUN ...
- python基础--python基本知识、七大数据类型等
在此申明一下,博客参照了https://www.cnblogs.com/jin-xin/,自己做了部分的改动 (1)python应用领域 目前Python主要应用领域: 云计算: 云计算最火的语言, ...
- front-end——HTML5/CSS3基础
概述 1.什么是前端 前端即网站前台部分,运行在PC端,移动端等浏览器上展现给用户浏览的网页,随着互联网技术的发展,html5,css3,前端框架的应用,跨平台响应式网页设计能够适应各种屏幕分辨率,完 ...
- Kubernetes 教程:根据 PID 获取 Pod 名称
原文链接:https://fuckcloudnative.io/posts/find-kubernetes-pod-info-from-process-id/ 在管理 Kubernetes 集群的过程 ...