C#上位机监控PLC通讯状态(多线程、异步、invoke使用技巧)

在实际的工程中一定要明白什么时候用多线程,什么时候用异步,只有这样才能解决窗口的卡顿感问题。新建一个测试工程:

添加S7.net通讯库

引用命名空间

using S7.net;

public partial class Form1:Form
{
//创建一个多线程,不能在主线程下一直占用。
    Plc plc = new Plc(CpuType.S71500,"192.168.0.102",0,1);
    public Form1()
    {
        InitializeComponent();
    }
private void Form1_Load(object sender,EventArgs e)
{
    Task task = new TaskFactory().StartNew(()=>
    {
        while(true)
        {
            if(!plc.IsConnected)
            {
                this.toolStripStatuesLabel1.Text="通讯异常";
                this.toolStripStatuesLabel1.BackColor=Color.Red;
                plc.Open();
            }
            if(plc.IsConnected)
            {
                this.toolStripStatuesLabel1.Text="通讯正常";
                this.toolStripStatuesLabel1.BackColor=Color.Green;
                bool b = (bool)plc.Read("DB9.DBX7.0");
            }
        }
    });
}
}

编写以上代码运行后会提示报错,因为背景的操作是属于主线程的,而现在的操作Task是多线程下的

public partial class Form1:Form
{
    Plc plc = new Plc(CpuType.S71500,"192.168.0.102",0,1);
    public Form1()
    {
        InitializeComponent();
    }
   private void Form1_Load(object sender,EventArgs e)
   {
   //创建一个多线程,不能在主线程下一直占用。
      Task task = new TaskFactory().StartNew(()=>
      {
        while(true)
        {
           this.Invoke(new Action(()=>   //得写在循环内部否则会被一直占用,而没响应主线程了
           {
              if(!plc.IsConnected)
              {
                this.toolStripStatuesLabel1.Text="通讯异常";
                this.toolStripStatuesLabel1.BackColor=Color.Red;
                //写个异步函数,因为此处的打开操作是个耗时操作。
                NewMethod();
             }
             if(plc.IsConnected)
             {
                this.toolStripStatuesLabel1.Text="通讯正常";
                this.toolStripStatuesLabel1.BackColor=Color.Green;
                //写个异步函数,因为此处的读取操作是个耗时操作。
                NewMethod1();
            }
         }
        }));
    });
        private async void NewMethod()
        {
            await Task.Run(()=>{
                try{
                    plc.Open();
                }catch
                {}
            });  //在PLC关闭的情况下打开会报错。
        }
        private async void NewMethod1()
        {
            await Task.Run(()=>{
                try{
                    bool b = (bool)plc.Read("DB9.DBX7.0");
                }catch
                {
                }
            });  //在PLC在关闭的情况下读取的会报错。
        }
}
}

多线程对主线程的操作必须写在Invoke体内。因为BackColor是主线程的

转载请注明出处:  https://www.cntworld.cn
智能工控 » C#上位机监控PLC通讯状态(多线程、异步、invoke使用技巧)

发表回复

提供最优质的资源集合

立即查看 了解详情