资源描述
Click to edit Master title style,Click to edit Master text styles,Second level,Third level,Fourth level,Fifth level,*,*,单击此处编辑母版标题样式,*,单击此处编辑母版标题样式,43,工控程序设计,工控程序设计,学习情景,2,串口设备的数据采集,学习情景,2.3,单个串口设备数据的连续接收,2.3.1,学习要点,1.,知识点:线程的概念,委托的概念和使用方法,线程的创建和启动,工作者线程和用户界面线程之间的数据传递,线程同步技,2.,技能点:工作者线程的创建,串口数据接收和处理操作的封装,2.3.2,任务描述,1.,在前一个情景中完成了接收和处理单一串口设备数据的工作任务。实际应用中,上位机需要连续地接收和处理下位机发送的数据,而且在等待和接收数据的时候,用户界面不能停止响应。接收数据和响应用户输入这两个工作在宏观上是同时进行的,为了满足该需求,必须采用多线程模式来进行程序设计。,2.,该教学情景通过“在工作者线程中接收,HSDZC,电能综合测试仪的”“,HSDZC,电能综合测试仪数据接收和处理操作的封装”这两个实施步骤达到连续接收接收单个串口设备(下位机)数据的目的。,学习情景,2.3,单个串口设备数据的连续接收,2.3.3,相关知识,1,多线程技术概述,(1),线程的概念,Windows,是一个抢占式多任务操作系统,在系统内核中提供了对多线程的支持,多线程技术可以让应用程序在一个耗时的操作中能够及时对用户操作进行响应,并且从宏观上达到多个任务“齐头并进”的目的,进程是应用程序的一个运行例程,是应用程序的一次动态执行过程。线程是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。每个进程至少需要一个执行线程,由系统自动创建,程序设计者可以根据需要创建其它线程。由于多个线程共享进程中的全局变量和系统资源,所以线程间的切换比较容易,通信也比较方便。,学习情景,2.3,单个串口设备数据的连续接收,(2).NET Framework,对多线程的支持,.NET,平台库提供了,Thread,类对线程进行处理,该类包含在,System.Threading,命名空间中,程序中需要包含语句“,using System.Threading;”,。编程人员可以通过创建一个,Thread,类的实例来创建一个线程,并通过,Thread,类提供的方法对线程进行管理。,Thread,类的常用属性和方法如下表:,表,2.3.1 Thread,类的常用属性和方法,学习情景,2.3,单个串口设备数据的连续接收,2,委托的概念和使用方法,C#,中的委托的作用相当于,C/C+,中的函数指针,函数指针是一个函数的入口地址。必修使用函数指针的场合是:程序员,A,编写了函数,f,,该函数中需要执行另外一个参数和返回值已经确定,但名字暂时不能确定函数,所以给函数设置一个函数指针类型的形式参数;当程序员,B,使用函数,f,时,定义函数,g,,并把,g,的入口地址作为实际参数传递给函数,f,,这样就可以在,f,中执行函数,g,了。,线程的启动是使用函数指针的一个典型例子,在启动线程之前,先要给操作系统指明线程启动后执行哪一函数中包含的代码,这时就要把函数的指针传递给创建线程的函数。,回调,(,完成后通知,),是使用函数指针的另外一个典型例子。如程序员,A,编写了负责接收网络数据的函数,f1,,程序员,B,编写了负责处理数据的函数,f2,,那么就可以把,f2,的函数指针作为参数传递给函数,f1,,当,f1,接收数据完毕后,自动调用,f2,。所以回调的特点是:站在程序员,B,的角度看,函数由自己编写,但是不由自己调用,且不知道什么时候被调用(因为网络速度有快有慢),函数编写者要做的就是把函数指针传递出去。,学习情景,2.3,单个串口设备数据的连续接收,定义委托的关键字是,delegate,,它是从,System.Delegate,类派生出来的。例如:,delegate int SomeDelegate(int p1,string p2);,/ int p1,和,string p2,是被引用函数的参数类型和名称。其中参数类型和参数的个数必须和被引用函数的类型与个数一致。,3,创建和启动线程,一个线程必须和一个方法的入口(委托)关联起来,线程启动后,自动从该入口进入,执行函数体中包含的内容。,C#,应用程序启动时,自动创建主线程,并进入,Main,方法开始执行,其它线程需要在程序里自己定义和启动。由于委托可以代表一个方法的入口,学习情景,2.3,单个串口设备数据的连续接收,所以创建线程实例时只需要在,Thread,类的构造方法里传入一个委托实例即可,这个委托名叫,ThreadStart,,已经在线程命名空间中定义作了定义:,public delegate void ThreadStart();,所以创建线程方式如下:,ThreadStart functionEntrance = new ThreadStart(threadFunction);,Thread t = new Thread(functionEntrance);,在委托,ThreadStart,的构造方法里面传入的是方法名,这个方法可以是静态方法,也可以是某个对象的方法。线程对象创建后,我们就可以调用其,Start,方法开始线程的执行了。,学习情景,2.3,单个串口设备数据的连续接收,我们可以在主线程里建立线程,也可以在线程里再创建线程,线程启动后会自动执行委托实例代表的方法,线程执行完后会自动销毁并释放其占用的资源。,在一个新线程中执行带参数的函数,操作步骤如下:,定义线程函数:,private void paramThreadFunction(object param),/,函数体,用,ParameterizedThreadStart,委托封装线程函数:,学习情,景,景,2.3,单个串,口,口设备,数,数据的,连,连续接,收,收,ParameterizedThreadStartfunctionEntrance=,newParameterizedThreadStart(paramThreadFunction);,创建,线,线程对,象,象,hreadt =new Thread(functionEntrance);,启动线,程,程,t.Start(param);/param,为传入,的,的参数,,,,可以,是,是任意,对,对象,学习情,景,景,2.3,单个串,口,口设备,数,数据的,连,连续接,收,收,4,线程同,步,步技术,多线程,应,应用程,序,序中的,的,的线程,启,启动后,,,,执行,的,的先后,顺,顺序是,无,无法预,知,知的,,通,通常情,况,况下多,个,个线程,会,会交错,执,执行。,但,但是在,多,多个线,程,程访问,共,共享数,据,据的情,况,况下,,必,必须对,数,数据的,访,访问进,行,行同步,。,。好比,有,有两路,车,车,一,路,路自东,向,向西,,一,一路自,南,南向北,运,运行,,在,在一个,十,十字路,口,口交汇,。,。在十,字,字路口,以,以外的,区,区域可,以,以看着,私,私有区,域,域,而,十,十字路,口,口则是,共,共有区,域,域,需,要,要红绿,灯,灯或交,警,警来维,护,护秩序,,,,即确,保,保在同,一,一时刻,只,只能有,一,一路车,进,进入,,而,而另外,一,一路车,必,必须等,待,待,这,就,就是现,实,实生活,中,中的线,程,程同步,问,问题,。,学习情,景,景,2.3,单个串,口,口设备,数,数据的,连,连续接,收,收,下面的,例,例子展,示,示了一,个,个读数,据,据线程,和,和一个,写,写数据,线,线程同,时,时运行,的,的情况,:,:,private staticinta =new int5;,staticvoidMain(string args),Threadt1=newThread(newThreadStart(threadFun1);,Threadt2=newThread(newThreadStart(threadFun2);,t1.Start();,t2.Start();,private staticvoid threadFun1()/,线程函,数,数,1,while(true),学习情,景,景,2.3,单个串,口,口设备,数,数据的,连,连续接,收,收,for(inti =0;i a.Length;i+) /,将数组,元,元素全,部,部输出,System.Console.Write(ai +);,System.Console.WriteLine();,private staticvoid threadFun2()/,线程函,数,数,2,intflag= 0,i;,while(true),for(i=0;i a.Length; i+)/,将数,组,组元,素,素全,部,部改,为,为,0,或,1,ai=flag;,flag=flag=0?,1:0;,学习,情,情景,2.3,单个,串,串口,设,设备,数,数据,的,的连,续,续接,收,收,下面,采,采用,Monitor,类来,进,进行,线,线程,同,同步,,,,使,数,数据,读,读、,写,写操,作,作称,为,为原,子,子操,作,作。,即,即达,到,到这,样,样的,目,目的,:,:在,线,线程,2,写数,据,据时,,,,线,程,程,1,等待,,,,在,线,线程,1,读数,据,据时,,,,线,程,程,2,等待,,,,使,每,每次,输,输出,的,的结,果,果全,部,部为,0,或全,部,部为,1,。,当调,用,用,Monitor,类的,Enter(Objectobj),方法,时,时,会获,取,取对,象,象,obj,的独,占,占权,直到,调,调用,Exit(Objectobj),方法,时,时,才会,释,释放,对,对,obj,的独,占,占权,。,。注,意,意调,用,用,Enter,方法,的,的次,数,数要,和,和,调用,Exit,方法,的,的次,数,数相,等,等。,Monitor,类还,提,提供,了,了,TryEnter,方法,该方,法,法尝,试,试获,取,取,obj,对象,的,的独,占,占权,当获,取,取独,占,占权,失,失败,时,时,将返,回,回,false,。实,现,现代,码,码如,下,下:,学习,情,情景,2.3,单个,串,串口,设,设备,数,数据,的,的连,续,续接,收,收,privatestaticinta=newint5;,privatestatic object obj =newobject();,static voidMain(string args),Thread t1 =newThread(new ThreadStart(threadFun1);,Thread t2 =newThread(new ThreadStart(threadFun2);,t1.Start();,t2.Start();,privatestatic voidthreadFun1(),while (true),Monitor.Enter(obj);/,线程,1,进入临界,区,区活动时,,,,线程,2,等待,for(inti =0;i a.Length; i+),System.Console.Write(ai + );,System.Console.WriteLine();,学习情景,2.3,单个串口,设,设备数据,的,的连续接,收,收,Monitor.Exit(obj); /,线程,1,出临界区,后,后,线程,2,才可以进,入,入,privatestatic voidthreadFun2(),intflag= 0,i;,while (true),Monitor.Enter(obj);/,线程,2,进入临界,区,区活动时,,,,线程,1,等待,for(i =0;i a.Length; i+),ai= flag;,flag= flag= 0?,1 :0;,Monitor.Exit(obj); /,线程,2,出临界区,后,后,线程,1,才可以进,入,入,学习情景,2.3,单个串口,设,设备数据,的,的连续接,收,收,5,工作者线,程,程向用户,界,界面线程,传,传递数据,用户界面,线,线程简称,UI,线程,其,主,主要特点,是,是能响应,Windows,消息,主,要,要负责接,收,收用户输,入,入和向用,户,户展示程,序,序执行结,果,果。为了,及,及时响应,用,用户的输,入,入,,UI,线程中不,应,应执行费,时,时的运算,,,,更不能,被,被阻塞。,工作者线,程,程一般用,于,于在后台,进,进行费时,运,运算或和,慢,慢速设备,打,打交道,,这,这种线程,不,不响应,Windows,消息。在,通,通信程序,中,中,数据,的,的发送和,接,接收耗费,的,的时间不,确,确定。为,了,了在通信,过,过程中能,够,够响应用,户,户输入,,通,通常在建,立,立一个或,多,多个工作,者,者线程,,在,在后台完,成,成通信任,务,务。,工作者线,程,程向运行,在,在,UI,线程中的,用,用户控件,传,传递数据,时,时,不能,直,直接对对,控,控件的属,性,性和方法,进,进行调用,,,,而要先,定,定义一个,委,委托,再,用,用控件的,Invoke,方法,切,换,换到,UI,线程去执,行,行委托所,指,指向的函,数,数,来更,新,新控件显,示,示的内容,。,。,在下面的,程,程序中,,工,工作线程,每,每循环完,一,一次,就,更,更新,UI,线程中的,控,控件属性,,,,向用户,报,报告当前,步,步骤。程,序,序界面和,后,后台代码,如,如下:,学习情景,2.3,单个串口,设,设备数据,的,的连续接,收,收,图,2.3.1,工作者线,程,程向,UI,线程传递,数,数据,privatevoidbtnRun_Click(objectsender,EventArgs e),ThreadStartfunEntrance= new ThreadStart(threadFun);,Thread t= new Thread(funEntrance);,t.IsBackground =true;,t.Start();,学习情景,2.3,单个串口,设,设备数据,的,的连续接,收,收,privatedelegatevoid crossThreadDelegate(int i); /,定义委托,voidshowValue(int i),lblReport.Text =,执行到了,第,第, +i +,步,;,privatevoidthreadFun(),crossThreadDelegatecdt= new crossThreadDelegate(showValue);,for(inti =1;i =5;i+),/Invoke,方法将当,前,前线程切,换,换到,UI,线程,再,执,执行委托,指,指向的函,数,数,this.Invoke(cdt,i);/this,指代当前,窗,窗口,Thread.Sleep(1000);/,延时,便,于,于看清中,间,间执行过,程,程,学习情景,2.3,单个串口,设,设备数据,的,的连续接,收,收,下面的程,序,序在工作,者,者线程的,线,线程函数,中,中直接使,用,用,lblReport.Text,属性,而,没,没有用,Invoke,方法:,privatevoidthreadFun(),for(inti =1;i =5;i+),lblReport.Text =,执行到了,第,第, +i +,步,;,Thread.Sleep(1000);,在运行时,会,会捕获到,图,图,2.4.2,所示的异,常,常:,学习情景,2.3,单个串口,设,设备数据,的,的连续接,收,收,图,2.3.2,后台线程,向,向,UI,线程传递,数,数据,学习情景,2.3,单个串口,设,设备数据,的,的连续接,收,收,使用委托,和,和,Invoke,方法会使,代,代码复杂,度,度增加,,在,在实际应,用,用中,可,以,以用匿名,委,委托来简,化,化代码:,privatedelegatevoid crossThreadDelegate();,privatevoidthreadFun(),for(inti =1;i recvBuf.maxLength) /,堆积数据太,多,多,学习情景,2.3,单个串口设,备,备数据的连,续,续接收,(,2,)派生出具,体,体类,CHSDZC,在,CPassiveCOMHelper,类中实现了,串,串口打开、,关,关闭、线程,创,创建、数据,接,接收等基础,操,操作,其中,有,有一个虚方,法,法,getBlock,,需要在派,生,生类中根据,具,具体情况实,现,现,下面实,现,现专门采集,HSDZC,电能综合测,试,试仪数据的,类,类,CHSDZC,:,classCHSDZC :CPassiveCOMHelper, /,构造方法,public CHSDZC(stringportName,intbaudRate,int dataBits, StopBits stopBits),: base(portName, baudRate, dataBits, stopBits),/,覆盖基类的,getBlock,方法,专门,针,针对,HSDZC,获取数据,学习情景,2.3,单个串口设,备,备数据的连,续,续接收,protectedoverride bytegetBlock(Listli),byte b =null;,if (li.Count =p +46),if (lip +1 = 0xFF &lip+ 2= 0xFF &lip+ 3= 0xFF),break; /,已经找到,,接,接收循环,if (p!= -1) /p,为数据帧的,起,起始位置,学习情景,2.3,单个串口设,备,备数据的连,续,续接收,b = new byte46;,li.CopyTo(p, b,0, 46); /,拷贝数据帧,到,到,b,数组,return b;/,返回找到的,完,完整数据帧,(,3,)在,UI,模块中使用,CHSDZC,类实现数据,采,采集,在前面所作,工,工作的基础,上,上编写,UI,模块就非常,轻,轻松了。在,UI,模块中不用,关,关心串口通,信,信、线程操,作,作等复杂问,题,题,只需要,创,创建,CHSDZC,对象并启动,它,它即可,当,有,有完整的数,据,据帧收到时,,,,会引发,DataReceived,事件,并自,动,动调用,hsdzc_DataReceived,方法处理数,据,据。不过这,里,里需要注意,的,的是,,hsdzc_DataReceived,是个回调函,数,数,虽然包,含,含在,Form6,类中,但是,在,在工作者线,程,程中进行调,用,用,需要跨,线,线程操作,UI,线程中的文,本,本框等控件,,,,因此把操,作,作控件的代,码,码封装到一,个,个匿名委托,中,中,并用,this.Invoke,进行调用。,学习情景,2.3,单个串口设,备,备数据的连,续,续接收,2.3.5,考核要点,学习情景,2.3,单个串口设,备,备数据的连,续,续接收,2.3.6,能力拓展,1.,什么是委托,,,,委托在什,么,么场合使用,,,,如何使用,委,委托?,2.,在什么情况,下,下需要使用,多,多线程技术,,,,使用,Thread,类要引入什,么,么命名空间,,,,如何创建,和,和启动线程,?,?,3.,如何将工作,者,者线程中的,数,数据显示在,UI,线程的控件,中,中?,4.,安照说明书,里,里规定的数,据,据格式,设,计,计一个,HSDZC,电能综合测,试,试仪的模拟,程,程序(包含,两,两种测量方,式,式)。,5.,在图,2.3.3,的窗体上增,加,加一个,Timer,控件,并结,合,合,1.1.4,小节的任务,二,二,将采集,到,到的输入功,率,率、输出功,率,率、功率因,数,数值存储到,Params,集合中(不,立,立即显示在,文,文本框中),,,,每隔,1,秒钟用,Params,集合中的值,刷,刷新文本框,的,的内容,9,、静,夜,夜四,无,无邻,,,,荒,居,居旧,业,业贫,。,。12,月,月-2212,月,月-22,Thursday,December29,2022,10,、雨中黄,叶,叶树,灯,下,下白头人,。,。13:05:1713:05:1713:05,12/29/2022 1:05:17 PM,11,、以我独,沈,沈久,愧,君,君相见频,。,。12月-2213:05:1713:05,Dec-2229-Dec-22,12,、故,人,人江,海,海别,,,,几,度,度隔,山,山川,。,。13:05:1713:05:1713:05,Thursday,December29,2022,13,、乍见翻疑,梦,梦,相悲各,问,问年。12月-2212月-2213:05:1713:05:17,December 29, 2022,14,、,他,他,乡,乡,生,生,白,白,发,发,,,,,旧,旧,国,国,见,见,青,青,山,山,。,。,。,。29,十,十,二,二,月,月20221:05:17,下,下,午,午13:05:1712,月,月-22,15,、比不,了,了得就,不,不比,,得,得不到,的,的就不,要,要。十二月221:05 下,午,午12月-2213:05,December29,2022,16,、行,动,动出,成,成果,,,,工,作,作出,财,财富,。,。2022/12/2913:05:1813:05:18,29December2022,17,、做,前,前,,能,能够,环,环视,四,四周,;,;做,时,时,,你,你只,能,能或,者,者最,好,好沿,着,着以,脚,脚为,起,起点,的,的射,线,线向,前,前。,。,。1:05:18,下,下午1:05,下,下,午,午13:05:1812,月,月-22,9,、,没,没,有,有,失,失,败,败,,,,,只,只,有,有,暂,暂,时,时,停,停,止,止,成,成,功,功,!,!,。,。12,月,月-2212,月,月-22,Thursday,December29,2022,10,、很多事情,努,努力了未必,有,有结果,但,是,是不努力却,什,什么改变也,没,没有。13:05:1813:05:1813:05,12/29/20221:05:18 PM,11,、,成,成,功,功,就,就,是,是,日,日,复,复,一,一,日,日,那,那,一,一,点,点,点,点,小,小,小,小,努,努,力,力,的,的,积,积,累,累,。,。,。,。12,月,月-2213:05:1813:05,Dec-2229-Dec-22,12,、世间,成,成事,,不,不求其,绝,绝对圆,满,满,留,一,一份不,足,足,可,得,得无限,完,完美。,。,。13:05:1813:05:1813:05,Thursday,December29, 2022,13,、不知香,积,积寺,数,里,里入云峰,。,。12月-2212月-2213:05:1813:05:18,December29,2022,14,、,意,意,志,志,坚,坚,强,强,的,的,人,人,能,能,把,把,世,世,界,界,放,放,在,在,手,手,中,中,像,像,泥,泥,块,块,一,一,样,样,任,任,意,意,揉,揉,捏,捏,。,。29,十,十,二,二,月,月20221:05:18,下,下,午,午13:05:1812,月,月-22,15,、楚,塞,塞三,湘,湘接,,,,荆,门,门九,派,派通,。,。十二,月,月221:05,下,下,午,午12,月,月-2213:05,December29,2022,16,、少年,十,十五二,十,十时,,步,步行夺,得,得胡马,骑,骑。2022/12/29 13:05:1813:05:18,29December2022,17,、空山,新,新雨后,,,,天气,晚,晚来秋,。,。1:05:18 下,午,午1:05 下,午,午13:05:1812月-22,9,、,杨,杨,柳,柳,散,散,和,和,风,风,,,,,青,青,山,山,澹,澹,吾,吾,虑,虑,。,。,。,。12,月,月-2212,月,月-22,Thursday,December29,2022,10,、阅,读,读一,切,切好,书,书如,同,同和,过,过去,最,最杰,出,出的,人,人谈,话,话。13:05:1813:05:1813:05,12/29/20221:05:18PM,11,、越是没有,本,本领的就越,加,加自命不凡,。,。12月-2213:05:1813:05,Dec-2229-Dec-22,12,、越,是,是无,能,能的,人,人,,越,越喜,欢,欢挑,剔,剔别,人,人的,错,错儿,。,。13:05:1813:05:1813:05,Thursday,December29,2022,13,、知人者,智,智,自知,者,者明。胜,人,人者有力,,,,自胜者,强,强。12月-2212月-2213:05:1813:05:18,December29,2022,14,、,意,意,志,志,坚,坚,强,强,的,的,人,人,能,能,把,把,世,世,界,界,放,放,在,在,手,手,中,中,像,像,泥,泥,块,块,一,一,样,样,任,任,意,意,揉,揉,捏,捏,。,。29,十,十,二,二,月,月20221:05:18,下,下,午,午13:05:1812,月,月-22,15,、最具挑战,性,性的挑战莫,过,过于提升自,我,我。十二月 221:05,下,下午12月-2213:05,December 29, 2022,16,、,业,业,余,余,生,生,活,活,要,要,有,有,意,意,义,义,,,,,不,不,要,要,越,越,轨,轨,。,。2022/12/2913:05:1813:05:18,29December2022,17,、一个人,即,即使已登,上,上顶峰,,也,也仍要自,强,强不息。1:05:19,下,下午1:05,下,下午13:05:1912月-22,MOMODA POWERPOINT,Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce id urna blandit, eleifend nulla ac, fringilla purus. Nulla iaculis tempor felis ut cursus.,感谢您的,下,下载观看,专家告诉,
展开阅读全文