C#--Modbus-一主多从-委托跨线程更新UI界面
2021/4/17 20:25:27
本文主要是介绍C#--Modbus-一主多从-委托跨线程更新UI界面,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
以下是学习笔记
一,接线图
3台仪表设备接在一起
二,界面设计:
三,代码实现:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using DAL; namespace ModbusDemo { //委托跨线程更新UI步骤【1】:声明一个delegate委托类型:UpdateDelegate。 delegate void UpdateDelegate(); public partial class FrmMain : Form { public FrmMain() { InitializeComponent(); this.Load += FrmMain_Load; } //委托跨线程更新UI步骤【2】:创建一个UpdateDelegate类型的对象。 UpdateDelegate updateGUI; Modbus objMod = new Modbus(); bool CommOK = false; bool ReadEnable = true; Dictionary<int, byte[]> CommValue = new Dictionary<int, byte[]>(); Dictionary<int, List<string>> CurrentValue = new Dictionary<int, List<string>>(); private void FrmMain_Load(object sender, EventArgs e) { //委托跨线程更新UI步骤【3】:给updateGUI(委托)对象绑定一个方法。 updateGUI = UpdateUI; for (int i = 0; i < 5; i++) { this.cmb_1stNum.Items.Add(i.ToString()); this.cmb_2ndNum.Items.Add(i.ToString()); this.cmb_3rdNum.Items.Add(i.ToString()); } if (objMod.OpenMyComm(9600, "COM3", 8, System.IO.Ports.Parity.None, System.IO.Ports.StopBits.One)) { CommOK = true; } else { MessageBox.Show("串口打开失败,请检查串口!", "串口打开 "); return; } Thread t = new Thread(new ThreadStart(Comm)); t.IsBackground = true; t.Start(); } /// <summary> /// 线程执行的方法 /// </summary> private void Comm() { while (CommOK) { //第一步:数据读取 //对于从站1,读取0-4共5个寄存器 CommValue[1] = objMod.ReadKeepReg(1, 0, 5); //对于从站2和从站3,读取0-3共4个寄存器 CommValue[2] = objMod.ReadKeepReg(2, 0, 4); CommValue[3] = objMod.ReadKeepReg(3, 0, 4); //第二步:数据解析 AnalyseData(); //第三步:更新到界面 //委托跨线程更新UI步骤【6】:在线程中调用委托。 updateGUI(); } } /// <summary> /// 数据解析 /// </summary> private void AnalyseData() { byte[] res; List<string> list; foreach (int item in CommValue.Keys) { switch (item) { //从站1 case 1: res = CommValue[1]; list = new List<string>(); if (res != null && res.Length == 10) { //计数值 Int32 res1 = ByteArrayToInt32(new byte[4] { res[0], res[1], res[2], res[3] }); list.Add(res1.ToString()); Int16 res2 = ByteArrayToInt16(new byte[2] { res[6], res[7] }); list.Add(res2.ToString()); } CurrentValue[1] = list; break; case 2: res = CommValue[2]; list = new List<string>(); if (res != null && res.Length == 8) { //计时值 Int32 res1 = ByteArrayToInt32(new byte[4] { res[0], res[1], res[2], res[3] }); list.Add(res1.ToString()); Int16 res2 = ByteArrayToInt16(new byte[2] { res[6], res[7] }); list.Add(res2.ToString()); } CurrentValue[2] = list; break; case 3: res = CommValue[3]; list = new List<string>(); if (res != null && res.Length == 8) { //计时值 Int32 res1 = ByteArrayToInt32(new byte[4] { res[0], res[1], res[2], res[3] }); list.Add(res1.ToString()); Int16 res2 = ByteArrayToInt16(new byte[2] { res[6], res[7] }); list.Add(res2.ToString()); } CurrentValue[3] = list; break; } } } /// <summary> /// 委托跨线程更新UI步骤【4】:更新UI的方法。 /// </summary> private void UpdateUI() { if (CurrentValue.Count == 3) { //判断该方法是否被主线程调用,也就是创建窗体控件的线程,当控件的InvokeRequired属性为ture时,说明是被主线程以外的线程调用。如果不加判断,会造成异常 if (this.InvokeRequired)//判断 { //委托跨线程更新UI步骤【5】:激活委托。 this.Invoke(updateGUI); } else { if (CurrentValue[1].Count>0) { this.txt_1stNum.Text = CurrentValue[1][0]; this.cmb_1stNum.Text = CurrentValue[1][1]; } if (CurrentValue[2].Count > 0) { this.txt_2ndNum.Text = CurrentValue[2][0]; this.cmb_2ndNum.Text = CurrentValue[2][1]; } if (CurrentValue[3].Count > 0) { this.txt_3rdNum.Text = CurrentValue[3][0]; this.cmb_3rdNum.Text = CurrentValue[3][1]; } } } } /// <summary> /// 4个字节转换成一个长整形 /// </summary> /// <param name="byteArray"></param> /// <returns></returns> private Int32 ByteArrayToInt32(byte[] byteArray) { if (byteArray.Length == 4) { return (Int32)(byteArray[3] + byteArray[2] * Math.Pow(2, 8) + byteArray[1] * Math.Pow(2, 16) + byteArray[0] * Math.Pow(2, 24)); } else { return 0; } } private Int16 ByteArrayToInt16(byte[] byteArray) { if (byteArray.Length == 2) { return (Int16)(byteArray[1] + byteArray[0] * Math.Pow(2, 8)); } else { return 0; } } private void btn_Set1_Click(object sender, EventArgs e) { objMod.PreSetKeepReg(1, 3, int.Parse(this.txt_Set1.Text.Trim())); } private void btn_Set2_Click(object sender, EventArgs e) { objMod.PreSetKeepReg(2, 3, int.Parse(this.txt_Set2.Text.Trim())); } private void btn_Set3_Click(object sender, EventArgs e) { objMod.PreSetKeepReg(3, 3, int.Parse(this.txt_Set3.Text.Trim())); } } }
这篇关于C#--Modbus-一主多从-委托跨线程更新UI界面的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2022-03-01沐雪多租宝商城源码从.NetCore3.1升级到.Net6的步骤
- 2024-11-18微软研究:RAG系统的四个层次提升理解与回答能力
- 2024-11-15C#中怎么从PEM格式的证书中提取公钥?-icode9专业技术文章分享
- 2024-11-14云架构设计——如何用diagrams.net绘制专业的AWS架构图?
- 2024-05-08首个适配Visual Studio平台的国产智能编程助手CodeGeeX正式上线!C#程序员必备效率神器!
- 2024-03-30C#设计模式之十六迭代器模式(Iterator Pattern)【行为型】
- 2024-03-29c# datetime tryparse
- 2024-02-21list find index c#
- 2024-01-24convert toint32 c#
- 2024-01-24Advanced .Net Debugging 1:你必须知道的调试工具