首页 > 代码库 > C# 使用代理实现线程间调用

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(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);            }        }    }}

 

C# 使用代理实现线程间调用