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里开发一个轻量.无锁的线程内通讯框架:并且也没有队列.消息.事件或任 ...
随机推荐
- 循序渐进VUE+Element 前端应用开发(16)--- 组织机构和角色管理模块的处理
在前面随笔<循序渐进VUE+Element 前端应用开发(15)--- 用户管理模块的处理>中介绍了用户管理模块的内容,包括用户列表的展示,各种查看.编辑.新增对话框的界面处理和后台数据处 ...
- 计算机网络期末实验考题(Pacekt Tracer搭建网络拓扑实现通信)
期末考试的这一道实验题目具体要求如下: 搭建一个包含5个路由器.两个交换机和3个PC机的连通网络,网络拓扑结构自定,网络IP地址,子网掩码等信息自定, 最后实现3个PC机互通.要求:1)3个PC ...
- MAC地址和交换机
数据链路层主要关注三个问题: 这个包是发给谁的?谁应该接收? 大家都在发,会不会产生混乱?有没有谁先发.谁后发的规则? 如果发送的时候出现了错误,怎么办? 数据链路层也称为MAC(Medium Acc ...
- IDEA添加注释常用的快捷键
1.行注释Ctrl+/ 2.块注释Ctrl+Shift+/ 3.生成类注释 输入/**,然后按回车 (idea上没有生成类注释快捷键的,可以看这里 :idea生成类注释和方法注释的正确方法 ) 4.生 ...
- Flutter-Tips
1.报错:flutter: Another exception was thrown: Could not find a generator for route RouteSettings原因是一个工 ...
- Thymeleaf从入门到精通
什么是Thymeleaf 大家好,我是bigsai,今天我们来学习Thymeleaf,如果你对Thymeleaf比较陌生也不要紧,它很容易学习与理解,并有着自己鲜明的特色. 开始之前,我们依旧问一个问 ...
- 快速配置webpack+vue项目
第一步:初始化项目 1.npm init 2. package name: (webpack+vue) webpackvue version: (1.0.0) description: this is ...
- gitlab的还原
源服务器: ip: 192.168.0.199 系统:CentOS7.2 内核: 3.10.0-327 gitlab版本: gitlab-ce-8.0.5 新服务器: ip: 192.168.0.19 ...
- 使用MacOS自带的SVN客户端
原文链接:https://jingyan.baidu.com/article/5552ef479c1554518ffbc92f.html 摘要:mac环境下有自带的SVN服务端和客户端,SVN是许多公 ...
- pandas_查看数据特征和统计信息
# 查看数据特征和统计信息 import pandas as pd # 读取文件 dataframe = pd.read_excel(r'C:\Users\lenovo\Desktop\总结\Pyth ...