多线程在VisualC#网络编程中的应用(1)一.简介在VisualC#中创建和使用线程:VisualC#中使用的线程都是通过自命名空间System.Threading中的Thread类经常实例化完成的。通过Thread类的构造函数来创建可供VisualC#使用的线程,通过Thread中的方法和属性来设定线程属性和控制线程的状态。以下Thread类中的最典型的构造函数语法,在VisualC#中一般使用这个构造函数来创建、初始化Thread实例。publicThread(ThreadStartstart);参数startThreadStart委托,它将引用此线程开始执行时要调用的方法。Thread还提供了其他的构造函数来创建线程,这里就不一一介绍了。表01是Thread类中的一些常用的方法及其简要说明:方法说明Abort调用此方法通常会终止线程,但会引起ThreadAbortException类型异常。Interrupt中断处于WaitSleepJoin线程状态的线程。Join阻塞调用线程,直到某个线程终止时为止。ResetAbort取消当前线程调用的Abor方法。Resume继续已挂起的线程。Sleep当前线程阻塞指定的毫秒数。Start操作系统将当前实例的状态更改为ThreadState.Running。Suspend挂起线程,或者如果线程已挂起,则不起作用。表01:Thread类的常用方法及其说明这里要注意的是在.Net中执行一个线程,当线程执行完毕后,一般会自动销毁。如果线程没有自动销毁可通过Thread中的Abort方法来手动销毁,但同样要注意的是如果线程中使用的资源没有完全销毁,Abort方法执行后,也不能保证线程被销毁。在Thread类中还提供了一些属性用以设定和获取创建的Thread实例属性,表02中是Thread类的一些常用属性及其说明:属性说明CurrentCulture获取或设置当前线程的区域性。CurrentThread获取当前正在运行的线程。IsAlive获取一个值,该值指示当前线程的执行状态。IsBackground获取或设置一个值,该值指示某个线程是否为后台线程。Name获取或设置线程的名称。Priority获取或设置一个值,该值指示线程的调度优先级。ThreadState获取一个值,该值包含当前线程的状态。表02:Thread类的常用属性及其说明二.本文的主要内容及程序调试和运行环境:本文的主要内容是介绍多线程给用VisualC#编写网络应用程序带来的更高性能提高。具体的做法是在VisualC#用二种不同的方法,一种采用了多线程,另一种不是,来实现同一个具体网络应用示例,此示例的功能是获取网络同一网段多个IP地址对应的计算机的在线状态和对应的计算机名称,通过比较这二种方法的不同执行效率就可知多线程对提高网络应用程序的执行效率是多么的重要了。以下是本文中设计到程序的调试和运行的基本环境配置:(1).微软公司视窗2000服务器版。(2).VisualStudio.Net2002正式版,.NetFrameWorkSDK版本号3705。三.扫描网络计算机的原理:下面介绍的这个示例的功能是通过扫描一个给定区间IP地址,来判断这些IP地址对应的计算机是否在线,如果在线则获得IP地址对应的计算机名称。程序判断计算机是否在线的是采用对给定IP地址的计算机进行DNS解析,如果能够根据IP地址解析出对应的计算机名称,则说明此IP地址对应的计算机在线;反之,如果解析不出,则会产生异常出错,通过对异常的捕获,得到此IP地址对应的计算机并不在线。为了更清楚地说明问题和便于掌握在VisualC#编写多线程网络应用程序的方法,本文首先介绍的是不基于多线程的网络计算机扫描程序的编写步骤,然后再在其基础上,把它修改成多线程的计算机扫描程序,最后比较这二个程序的执行效率,你就会发现线程在网络编程中的重要作用了。四.VisualC#实现不基于多线程的网络计算机扫描程序以下是在VisualC#实现不基于多线程的网络计算机扫描程序步骤:1.启动VisualStudio.Net,并新建一个VisualC#项目,项目名称为【扫描网络计算机】。2.把VisualStudio.Net的当前窗口切换到【Form1.cs(设计)】窗口,并从【工具箱】中的【Windows窗体组件】选项卡中往Form1窗体中拖入下列组件,并执行相应操作:四个NumericUpDown组件,用以组合成一个IP地址区间。一个ListBox组件,用以显示扫描后的结果。一个ProgressBar组件,用以显示程序的运行进度。四个Label组件,用以显示提示信息。一个GroupBox组件。一个Button组件,名称为button1,并在这组件拖入窗体后,双击button1,这样VisualStudio.Net就会产生这button1组件Click事件对应的处理代码。界面设置如下图:图01:【扫描网络计算机】项目的设计界面3.把VisualStudio.Net的当前窗口切换到【Form1.cs】,进入Form1.cs文件的编辑界面。在Form1.cs头部,用下列代码替换系统缺省的导入命名空间代码:usingSystem;usingSystem.Drawing;usingSystem.Collections;usingSystem.ComponentModel;usingSystem.Windows.Forms;usingSystem.Data;usingSystem.Net.Sockets;usingSystem.Net;4.用下列代码替换Form1.cs中的button1的Click时间对应的处理代码,下列代码的功能是扫描给定的IP地址区间,并把扫描结果显示出来。privatevoidbutton1_Click(objectsender,System.EventArgse){listBox1.Items.Clear();//清楚扫描结果显示区域DateTimeStartTime=DateTime.Now;//获取当前时间stringmask=numericUpDown1.Value.ToString()+.+numericUpDown2.Value.ToString()+.+numericUpDown3.Value.ToString()+.;intMin=(int)numericUpDown4.Value;intMax=(int)numericUpDown5.Value;if(MinMax){MessageBox.Show(输入的IP地址区间不合法,请检查!,错误!);return;}//判断输入的IP地址区间是否合法progressBar1.Minimum=Min;progressBar1.Maximum=Max;inti;for(i=Min;i=Max;i++){stringip=mask+i.ToString();IPAddressmyIP=IPAddress.Parse(ip);//根据给定的IP地址字符串,处境IPAddress实例try{IPHostEntrymyHost=Dns.GetHostByAddress(myIP);stringHostName=myHost.HostName.ToString();listBox1.Items.Add(ip+名称为:+HostName);}catch{listBox1.Items.Add(ip+主机没有响应!);}progressBar1.Value=i;}//扫描给定IP地址对应的计算机是否在线DateTimeEndTime=DateTime.Now;TimeSpants=EndTime-StartTime;//获得扫描网络计算机所使用的时间label4.Text=ts.Seconds.ToString()+秒;MessageBox.Show(成功完成检测!,提示);progressBar1.Value=Min;}由于上述代码比较简单,并且在代码中的注释也比较详细,这里就不加以解释了,但请注意上面代码中对时间日期类型数据的处理方法。因为有很多人曾经向我讯问过类似问题。多线程在VisualC#网络编程中的应用(2)整理51cto.com我要评论(3)摘要:本文详细讲解了多线程在VisualC#网络编程中的应用标签:网络C#Oracle帮您准确洞察各个物流环节5.至此,不基于多线程的【扫描网络计算机】项目的全部工作就完成了,程序的执行是很机械的,其方法是对每一个IP按照顺序进行DNS解析,并得到解析结果,所以程序的执行时间和扫描的IP地址区间段大小成正比。图02是此程序运行后,扫描10.138.198.1至10.138.198.10这个IP地址区间计算机后的运行界面。整个程序的运行时间为43秒:图02:不基于多线程的【扫描网络计算机】项目的运行界面五.把【扫描网络计算机】程序修改成基于多线程的程序:在修改成多线程程序之前,必须面对并解决下面几个问题:1.线程是无返回值的,所以在线程中处理、调用的应是一个过程,所以要把扫描IP地址对应的计算机的代码给包装成一个过程。2.放在线程中处理的过程,因为没有返回值,从而无法向主程序(进程)传递数值。但扫描IP地址对应的计算机的过程却要向主程序(进程)传递IP地址是否在线的数据,所以在修改成多线程程序之前,必须从线程往主程序(进程)传递数据的问题。下面是在【扫描网络计算机】项目的基础上,把它修改成基于多线程程序的具体实现步骤:1.由于程序中使用到线程,所以在Form1.cs代码首部,导入命名空间代码区中加入下列代码,下列代码是导入Thread类所在的命名空间。usingSystem.Threading;2.在Form1.cs代码的namespace代码区加入下列语句,下列语句是定义一个delegate:publicdelegatevoidUpdateList(stringsIP,stringsHostName);3.在Form1.cs中的定义Form1的class代码区定义加入下列代码,下列代码是定义一个变量,用以存放程序执行的时间:privateSystem.DateTimeStartTime;4.在Form1.cs代码的Main函数之后,添加下列代码,下列代码是创建一个名称为ping的Class,这个Class能够通过其设定的属性接收给定的IP地址字符串,并据此来判断此IP地址字符串对应的计算机是否在线,并通过其设定的HostName属性接收从线程传递来的数据。publicclassping{publicUpdateListul;publicstringip;//定义一个变量,用以接收传送来的IP地址字符串publicstringHostName;//定义一个变量,用以向主进展传递对应IP地址是否在线数据publicvoidscan(){IPAddressmyIP=IPAddress.Parse(ip);try{IPHostEntrymyHost=Dns.GetHostByAddress(myIP);HostName=myHost.HostName.ToString();}catch{HostName=;}if(HostName==)HostName=主机没有响应!;if(ul!=null)ul(ip,HostName);}//定义一个过程(也可以看出为方法),用以判断传送来的IP地址对应计算机是否在线}5.在Form1.cs中添加完上述代码后,再添加下列代码:voidUpdateMyList(stringsIP,stringsHostName){lock(listBox1){listBox1.Items.Add(sIP++sHostName);if(progressBar1.Value!=progressBar1.Maximum){progressBar1.