截至目前为止,C#上位机入门系列我们已经发了九篇。
C#上位机开发入门(1)
C#上位开发入门(2)
C#上位机开发入门(3)
C#上位机开发入门(4)
C#上位机开发入门(5)
C#上位机开发入门(6)-通信(上)
C#上位机开发入门(7)-通信(下)
C#上位机开发入门(8)-轮询
在开始之前,我们先介绍两个概念。进程:内存中运行的应用程序。一个应用程序就是一个进程,比如Word、Excel等。
线程:线程是进程中的⼀个执⾏单元,用于完成一个特定功能。一个进程通常包含了若干线程。
WinForm程序在运行时,如果我们不做异步处理。那么它所有的代码都是在UI线程中排队执行。所有的方法、事件就像在同一个任务线上。如果前面的执行时间长了,就会造成后面的延时。严重时就会影响用户的使用体验。
为了提高程序执行效率,提升用户使用体验。在很多应用中,尤其是C#上位机程序,我们都需要使用异步编程技术,也就是把一些耗时较长的操作放到一个单独的线程中执行。在C#编程中,我们一般使用任务并行库 (TPL)来实现异步编程。在上一节中,我们使用的 Task.Run(ReadData)就是以异步的方式来读取PLC数据。在TPL异步编程模型中,一个完成特定工作的代码片段可以定义为任务。我们通过“System.Threading.Tasks”名称空间下面的Task类可以使用单独的线程来执行这个任务。下面我们用异步的方式来对上一节的读取PLC数据的小例子进行重构。首先我们通过NuGet安装控件Agauge。Agauge是一款被广泛使用的仪表盘控件,功能强大,配置灵活。安装后我们拖一个Agauge控件到窗体上,修改窗体的“Text”属性为“PLC数据采集”。
它的默认样式并不好看。我们可以通过设置它的属性调整它的样式。下图是我们调整后的样式。
然后再拖两个Label控件到窗体上,分别设置它们的Text属性为温度和流量。现在它就是下面这个样子了。
我们把上一节例子中的对PLC的操作代码放到一个方法中。代码如下:
private void GetData(){
Sharp7.S7Client plc = new Sharp7.S7Client(); plc.Disconnect(); plc.ConnectTo("192.168.0.12", 0, 1);
if (plc.Connected) { while (true) { //线程挂起,1000表示1秒钟 //也就是数据每秒钟更新一次 Thread.Sleep(1000); byte[] data = new byte[1024]; plc.ReadArea(0x84, 1, 8, 8, 0x02, data); //Invoke表示在UI线程上执行该段代码 aGauge1.Invoke(new Action(() => { aGauge1.Value = Sharp7.S7.GetRealAt(data, 0); })); aGauge2.Invoke(new Action(() => { aGauge2.Value = Sharp7.S7.GetRealAt(data, 4); }));
} } }然后在窗体的Load事件中用Task执行该任务即可。
private void Form1_Load(object sender, EventArgs e) { Task.Run(GetData); }这样随着程序的启动,后台的数据采集任务自动执行,并且只有当窗体被关闭时任务才会停掉。数据采集任务是异步执行的,即使很大的数据量,我们在拖动窗体时会感觉不到丝毫的卡顿。
|