实现功能:
后台线程改变窗体控件(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(1000 * time);// 间隔1秒刷新页面 } }); threadStatus.Start(); } private Color GetBackColor(string status) { if (status == "0") { return Color.Silver;// 灰色 } else if (status == "1") { return Color.LawnGreen;// 绿色 } else if (status == "2") { return Color.Gold;// 黄色 } else if (status == "3") { return Color.Orange;// 橙色 } else if (status == "4") { 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); } } } }
时间: 2024-10-29 06:49:48