实现功能:

后台线程改变窗体控件(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. easyui获取datagrid中的某一列的所有值

    function getCol(){ var rows = $("#dg").datagrid("getRows"); var total = "&q ...

  2. js 自定义阻止事件冒泡函数

    // 以下改方法全兼容Chrome function stopBubble(event){ if(event.stopPropagation){   // 兼容火狐(firebox) event.st ...

  3. C#串模板

    c# 6.0 的语言特性,功能类似string.formate,更方便的地方在于不要像format一样使用索引,可以直接使用变量. 使用方法如下: string name = "zhangs ...

  4. 像计算机科学家一样思考Python(第2版)|百度网盘免费下载|Python新手入门资料

    像计算机科学家一样思考Python(第2版)|百度网盘免费下载 提取码:01ou 内容简介  · · · · · · 本书以培养读者以计算机科学家一样的思维方式来理解Python语言编程.贯穿全书的主 ...

  5. (一) BIO,NIO, 阻塞,非阻塞,你懂了吗

    一般来说,一个输入操作通常包括两个阶段: .等待数据准备好: .从内核向进程复制数据 是否同步的判断依据是: 是否 针对的 整个过程,即2个阶段,是否有阻塞 是否阻塞的判断依据是: 按 程序等待消息通 ...

  6. MySQL三种InnoDB、MyISAM和MEMORY存储引擎对比

    什么是存储引擎? MySQL中的数据用各种不同的技术存储在文件(或者内存)中.这些技术中的每一种技术都使用不同的存储机制.索引技巧.锁定水平并且最终提供广泛的不同的功能和能力.通过选择不同的技术,你能 ...

  7. PHP xml_set_default_handler() 函数

    定义和用法 xml_set_default_handler() 函数为 XML 解析器建立默认的数据处理器.高佣联盟 www.cgewang.com 该函数规定在只要解析器在 XML 文件中找到数据时 ...

  8. luogu P2304 [NOI2015]小园丁与老司机 dp 上下界网络流

    LINK:小园丁与老司机 苦心人 天不负 卧薪尝胆 三千越甲可吞吴 AC的刹那 真的是泪目啊 很久以前就写了 当时记得特别清楚 写到肚子疼.. 调到胳膊疼.. ex到根不不想看的程度. 当时wa了 一 ...

  9. Python PIL方式打开的图片判断维度

    1. PIL方式打开的图片判断维度    好久没更新啦,哈哈哈~~!今天跟宝宝们分享一篇如何判断灰度图像和彩色图像维度的方法.我们在读取灰度图像和彩色图像时,发现读取出来的图片维度不同,当我们要做后续 ...

  10. java -jar .jar中没有主清单属性

    pom里加上 <build> <plugins> <plugin> <groupId>org.springframework.boot</grou ...