对项目进行代码重构.docx
- 文档编号:3571357
- 上传时间:2023-05-06
- 格式:DOCX
- 页数:16
- 大小:65.57KB
对项目进行代码重构.docx
《对项目进行代码重构.docx》由会员分享,可在线阅读,更多相关《对项目进行代码重构.docx(16页珍藏版)》请在冰点文库上搜索。
对项目进行代码重构
对项目进行代码重构
临近公司放假,也好在年前对这次项目的一项总结(包括代码)。
刚分配到这份项目时,我认为自己可以完成这次的项目,但是在项目的开发过程中,还是遇到许多的问题,总的来说,分为以下几点:
1.前期对项目的背景不是很清楚(我一开始以为只要拿到项目就开始Coding,完成项目,其实不是这样);
2.文档写的不够完善(只写了需求分析、概要设计、没有数据库设计,因为文件都是存放在XML文档里);
3.对使用的技术不会(操作RS232串口,以前在学校从来没学过这些,当然,也不需要学习这些。
本人认为,自己主动去学和学校所教最大的区别在于主动是有意识的去学,而学校所教是被动的);
4.与老板(客户)的沟通不够,客户那边一有新的需求,就马上换成新的需求,然后换来换去,弄的心情很不爽,特别是一个项目需要分成好几种类型,比如,四川省的我要这种,福建省的我要那种,北京市的又是另外的,而且还是同时更新。
所以改的比较痛苦,也很纠结。
(现在已改用OO的方法);
5.最重要的是我自己对技术看的太轻松了,我认为技术会了就是会了,其实太天真了~~(其实是看个人的心态拉,我认为自己还Ok)。
所以,我一直在改变、进步!
好了,下面是项目中一个串口操作类重构后的Code。
这里我专门写了一个类来处理对串口的操作,主要是write、read,其中有用到包括delegate、event、lock、多线程。
首先,实例化串行端口,有端口名称波特率奇偶校验位数据位停止位这些。
然后在Program实例化这个串口操作类。
SettingClasssc=newSettingClass();
publicclassSettingClass
{
///
///实例化串行端口资源端口名称波特率奇偶校验位数据位停止位.
///
publicstaticSerialPortserPort=null;
//声明委托
publicdelegatevoidInsertData(byte[]ByData);
//声明事件
publicstaticeventInsertDataGetData;
复制代码
写个构造函数,来处理串口对象的初始化
///
///构造函数,处理串口对象的初始化.
///
publicSettingClass()
{
try
{
serPort=newSerialPort("COM1",9600,Parity.None,8,StopBits.One);
serPort.DataReceived+=newSerialDataReceivedEventHandler(serPort_DataReceived);
serPort.Open();
}
catch(Exceptionex)
{
System.Windows.Forms.MessageBox.Show("未发现到串口COM1,请检查.!
\n"+ex.Message,"错误警告");
}
}
复制代码
我们还可以写个带参的构造函数,用来后续选择端口的初始化
///
///后续可以选择COM端口初始化
///
///
///
///
///
///
publicSettingClass(stringportName,intbaudRate,Parityparity,intdataBits,StopBitsstopBits)
{
try
{
serPort=newSerialPort(portName,baudRate,parity,dataBits,stopBits);
serPort.DataReceived+=newSerialDataReceivedEventHandler(serPort_DataReceived);
serPort.Open();
}
catch(Exceptionex)
{
System.Windows.Forms.MessageBox.Show("未发现到串口COM1,请检查.!
\n"+ex.Message,"错误警告");
}
}
复制代码
在操作serialport的时候,如果需要实行实时的监听来自设备的数据包,那么,在SerialPort类中有DataReceived事件,当串口的读缓存有数据到达时则触发DataReceived事件。
(这个在上一篇文章中有,这里只是提一下)
///
///处理来自设备的数据.事件.
///
///缓存数组
List
privatevoidserPort_DataReceived(objectsender,SerialDataReceivedEventArgse)
{
try
{
//获取缓冲区的字节个数.
intintToRead=serPort.BytesToRead;
//声明临时数组存储串口数据.
byte[]byteData=newbyte[intToRead];
//读取来自缓冲区的数据.
serPort.Read(byteData,0,byteData.Length);
byte[]bytedata=newbyte[byteData.Length];
//把接收到的数据保存到缓存里
for(inti=0;i { bytedata[i]+=byteData[i]; buffer_list.Add(bytedata[i]); } lock(_syncLock) { //开启新线程 Threadth=newThread(newThreadStart(ReturnBytaData)); th.Start(); //if(th.IsAlive) //{ //th.Abort(); //} } } catch{} } privatestaticreadonlyobject_syncLock=newobject(); 复制代码 在上面这个事件里面,可以看到我声明了一个缓存数组来接收数据,作用是: 如果设备发包只发了一个、或者多个、又或者1个半,因为包是由Code+Length+Data+CRC组成,接收的时候怕只接收到了Code+Length,后面的没接收到,那么这个buffer的用处就来了,可以把前面的包和后面的包拼接成一个完整的包,然后传输到form的接收函数里。 设备发的数据包不可能只发一个Code+Length,后面在发一个Code+Length,规则协议和TCP传输原理一样。 下面的函数是用来处理从设备接收到的数据包,最后只返回Code和Data,返回Code是因为我一个界面上有不同的命令,但是会有相同的参数,视情况而定。 在这个函数中,也处理了 buffer缓存,对设备的数据包进行校验。 note: 下面代码第19行,返回的是setok,返回的是成功的数据包格式,需要进行处理。 复制代码 1/// 2///校验从设备得到的数据包 3/// 4/// 5/// 6publicvoidReturnBytaData() 7{ 8try 9{ 10//查询缓存是否还存在完整数据包 11while(buffer_list.Count>4) 12{ 13//缓存里第一个数据包 14intbytelength=buffer_list[1]; 15 16//声明需要返回的数据包 17byte[]returndata=newbyte[bytelength-1]; 18 19if(bytelength! =101) 20{ 21//把缓存内完整的数据包遍历到字节数组 22byte[]returnbytedata=newbyte[bytelength+2]; 23for(inti=0;i 24{ 25returnbytedata[i]+=buffer_list[i]; 26} 27 28//判断数据包的数据是否真实 29if(bytelength==returnbytedata.Length-2) 30{ 31//得到高八位、低八位 32bytej1=returnbytedata[returnbytedata.Length-2]; 33bytej2=returnbytedata[returnbytedata.Length-1]; 34 35intsum=0; 36 37//校验高八位、低八位. 38for(intj=0;j 39{ 40sum+=returnbytedata[j]; 41} 42byteg=(byte)(sum>>8); 43byted=(byte)(sum); 44if(j1==g&&j2==d) 45{ 46//得到datadata=-crc,-code,-length 47intdatalength=returnbytedata.Length-4; 48byte[]byteData=newbyte[datalength]; 49Array.Copy(returnbytedata,2,byteData,0,datalength); 50 51//得到code 52byte[]bytecode=newbyte[1]; 53Array.Copy(returnbytedata,0,bytecode,0,1); 54 55//返回code+data 56for(inti=0;i 57{ 58returndata[i]+=bytecode[i]; 59} 60for(intn=0;n 61{ 62returndata[n+1]+=byteData[n]; 63} 64 65buffer_list.RemoveRange(0,returnbytedata.Length); 66 67if(GetData! =null) 68{ 69//绑定到事件 70GetData(returndata); 71} 72} 73else 74{ 75buffer_list.RemoveRange(0,returnbytedata[1]+2); 76return; 77} 78} 79else 80{ 81return; 82} 83} 84else 85{ 86buffer_list.RemoveRange(0,buffer_list.Count); 87} 88} 89} 90catch{} 91} 复制代码 最后面的是接收来自form传过来的data. /// ///处理各个窗体传来的数据.各窗体只需要传送命令+数据即可. /// /// publicstaticvoidInsertserPortData(byte[]Data) { try { //因为各窗体发来的数据不包括CRC校验,所以长度+2. byte[]byteText=newbyte[Data.Length+2]; intsum=0; for(inti=0;i { byteText[i]+=Convert.ToByte(Data[i]); } //遍历sum的累加和,判断高八位和低八位. for(intn=0;n { sum+=byteText[n]; } //高八位. byteg=(byte)(sum>>8); //低八位. byted=(byte)(sum); //把检验加到字节数组中. byteText[byteText.Length-2]+=g; byteText[byteText.Length-1]+=d; //写入串口. serPort.Write(byteText,0,byteText.Length); } catch{} } 复制代码 最后,在需要接收数据包的form里面注册下这个事件。 SettingClass.GetData+=newSettingClass.InsertData(SettingClass_GetData); 下面的ByData是数据包(去除Length+CRC). voidSettingClass_GetData(byte[]ByData) { //处理接收到的数据包,显示到界面里... } 复制代码 这个项目对我的意义重大,我会一直对它进行重构下去。 下次应该就是用OO的方法来写文章了。 这个项目是我今年毕业以来独立负责的第一个项目。 所以,帮助真的很大,在这里我非常感谢我的公司,相信我,给了我锻炼的机会,也很感谢我的同事FHW、LB、FBY、RJB等。 操作串口通信类(IO.Ports)-SerialPort 公司项目接近尾部,从刚开始接触SerialPort到现在,用的最多算是它了。 所以,现在做个总结。 刚开始接到这个项目的时候,就从没接触过SerialPort,不知道如何下手,像最基本的PortName(通信端口)、BaudRate(波特率)、Parity(奇偶校验)、DataBits(数据位长度)、StopBits(停止位数)都不知道,后来网上google别人的经验,知道了最基本的用法,原来串口通信还需要下层的同事把协议写好,烧到硬件上去。 串口的使用: 1,串口控件位于工具箱—组件—SerialPort,拖动到窗体上,设置属性(Name),命名。 可在属性处进行设置,也可以在后台代码页进行手动写: 需导入命名空间: usingSystem.IO.Ports; /// ///串行端口资源端口名称波特率奇偶校验位数据位停止位 /// publicSerialPortport=newSerialPort("COM1",115200,Parity.None,8,StopBits.One); 复制代码 设置好串行端口等属性之后,便可以操作串口进行通信了,如要对设备进行全部开启操作。 /// /////设备全开、关 /// protectedvoidAllOpenOrClose() { try { //打开串口 port.Open(); //判断是否选中开 if(chb_CheckAll.Checked==true) { //用字节的形式发送数据全开解释: order1是控制命令,后面是2个byte的校验(高8位与低8位),0x00可以不写,直接写成(byte)((order1)>>8) byte[]b={order1,(byte)((order1+0x00)>>8),(byte)(order1+0x00)}; //把b数组中的数据以字节的形式写入串行端口 port.Write(b,0,b.Length); //提示信息! lab_Message.Text="设备已经全部打开! "; } else { //用字节的形式发送数据全关 byte[]b={order2,(byte)((order2+0x00)>>8),(byte)(order2+0x00)}; v.port.Write(b,0,b.Length); lab_Message.Text="设备已经全部关闭! "; } //关闭串口记得开启端口之后一定要关闭,和ADO.NET的Connection对象一样,用过之后必须关闭。 port.Close(); } catch(Exceptionex) { //捕获的异常信息 MessageBox.Show(ex.Message,"提示"); } } 复制代码 2,如果要对设备的状态进行实时监听,有一个很好的事件,在SerialPort类中有DataReceived事件,当串口的读缓存有数据到达时则触发DataReceived事件,其中SerialPort.ReceivedBytesThreshold属性决定了当串口读缓存中数据多少个时才触发DataReceived事件,默认为1。 我们把串口的属性定义在InitializeComponent()方法下面,(不会连这个方法都不知道把? ! ! )。 在页面命名空间下的第一个方法,是VisualStudio设计器自动生成的方法。 publicSettingsTimePlay() { InitializeComponent(); //串行端口号 seriaSettingPlay.PortName="COM1"; //波特率 seriaSettingPlay.BaudRate=115200; //奇偶校验位 seriaSettingPlay.Parity=Parity.None; //数据位 seriaSettingPlay.DataBits=8; //停止位 seriaSettingPlay.StopBits=StopBits.One; textChanged+=newUpdateTextEventHandler(ChangeText); try { //打开串口 seriaSettingPlay.Open(); } catch(Exceptionex) { //捕获的异常信息,没检查到串口或串口设置不正确。 MessageBox.Show("请检查是否已经连接串口! \n"+ex.Message,"提示"); } } 复制代码 属性定义完成之后,需要, //定义委托 privatedelegatevoidGetText(stringtext); //定义事件 privateeventGetTexttextChanged; //事件处理方法 privatevoidChangeText(stringtext) { //这里为处理接收到的值,赋值到控件上。 ........... } 复制代码 现在就是DataReceived事件进行实时监听了, //定义接收的字节 privatebyte[]Data=newbyte[8]; privatevoidseriaSettingPlay_DataReceived(objectsender,SerialDataReceivedEventArgse) { //读取来自监听到的字节 seriaSettingPlay.Read(be,0,be.Length); //把第一个命名赋值到text变量 text=be[0].Tostring(); seriaSettingPlay.DiscardInBuffer(); this.Invoke(textChanged,newstring[]{text}); } 复制代码 最后,记得在Load事件里去读取。 还有取出来的数据最好也进行校验,因为不校验容易受到干扰。 希望对大家学习串口知识有所帮助。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 项目 进行 代码