科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件多线程在Visual C#网络编程中的应用

多线程在Visual C#网络编程中的应用

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

Visual C#中使用的线程都是通过自命名空间System.Threading中的Thread类经常实例化完

作者:阿虎 来源:yesky 2007年11月13日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
五.把【扫描网络计算机】程序修改成基于多线程的程序

  在修改成多线程程序之前,必须面对并解决下面几个问题:

  1. 线程是无返回值的,所以在线程中处理、调用的应是一个过程,所以要把扫描IP地址对应的计算机的代码给包装成一个过程。

  2. 放在线程中处理的过程,因为没有返回值,从而无法向主程序(进程)传递数值。但扫描IP地址对应的计算机的过程却要向主程序(进程)传递IP地址是否在线的数据,所以在修改成多线程程序之前,必须从线程往主程序(进程)传递数据的问题。

  下面是在【扫描网络计算机】项目的基础上,把它修改成基于多线程程序的具体实现步骤:

  1. 由于程序中使用到线程,所以在Form1.cs代码首部,导入命名空间代码区中加入下列代码,下列代码是导入Thread类所在的命名空间。

using System.Threading ;

  2. 在Form1.cs代码的namespace代码区加入下列语句,下列语句是定义一个delegate:

public delegate void UpdateList ( string sIP , string sHostName ) ;

  3. 在Form1.cs中的定义Form1的class代码区定义加入下列代码,下列代码是定义一个变量,用以存放程序执行的时间:

private System.DateTime StartTime ;

  4. 在Form1.cs代码的Main函数之后,添加下列代码,下列代码是创建一个名称为ping的Class,这个Class能够通过其设定的属性接收给定的IP地址字符串,并据此来判断此IP地址字符串对应的计算机是否在线,并通过其设定的HostName属性接收从线程传递来的数据。

public class ping
{
 public UpdateList ul ;
 public string ip ;
 //定义一个变量,用以接收传送来的IP地址字符串
 public string HostName ;
 //定义一个变量,用以向主进展传递对应IP地址是否在线数据
 public void scan ( )
 {
  IPAddress myIP = IPAddress.Parse ( ip ) ;
  try
  {
   IPHostEntry myHost = Dns.GetHostByAddress ( myIP );
   HostName = myHost.HostName.ToString ( ) ;
  }
  catch
  {
   HostName = "" ;
  }
  if (HostName == "")
   HostName = " 主机没有响应!";
  if ( ul != null)
   ul ( ip , HostName ) ;
 }
 //定义一个过程(也可以看出为方法),用以判断传送来的IP地址对应计算机是否在线
}

  5. 在Form1.cs中添加完上述代码后,再添加下列代码:

void UpdateMyList ( string sIP , string sHostName )
{
 lock ( listBox1 )
 {
  listBox1.Items.Add ( sIP + " " + sHostName ) ;
  if ( progressBar1.Value != progressBar1.Maximum )
  {
   progressBar1.Value++ ;
  }
  if ( progressBar1.Value == progressBar1.Maximum )
  {
   MessageBox.Show ( "成功完成检测!" , "提示" ) ;
   DateTime EndTime = DateTime.Now ;
   TimeSpan ts = EndTime-StartTime ;
   label4.Text = ts.Seconds.ToString ( ) + "秒" ;
   //显示扫描计算机所需要的时间
   progressBar1.Value = progressBar1.Minimum ;
  }
 }
}

  6. 用下列代码替换Form1.cs中button1的Click事件对应的处理代码,下列代码功能是创建多个扫描给定IP地址区间对应的计算机线程实例,并显示扫描结果。

private void button1_Click(object sender, System.EventArgs e)
{
 listBox1.Items.Clear ( ) ;
 //清楚扫描结果显示区域
 StartTime = DateTime.Now ;
 //获取当前时间
 string mask = numericUpDown1.Value.ToString ( ) + "." + numericUpDown2.Value.ToString ( ) +
"." + numericUpDown3.Value.ToString ( ) + "." ;
 int Min = ( int ) numericUpDown4.Value ;
 int Max = ( int ) numericUpDown5.Value ;
 if ( Min > Max )
 {
  MessageBox.Show ( "输入的IP地址区间不合法,请检查!" , "错误!" ) ;
  return ;
 }
 //判断输入的IP地址区间是否合法
 int _ThreadNum = Max - Min + 1 ;
 Thread[] mythread = new Thread [ _ThreadNum ] ;
 //创建一个多个Thread实例
 progressBar1.Minimum = Min ;
 progressBar1.Maximum = Max + 1 ;
 progressBar1.Value = Min ;
 int i ;
 for (i = Min ; i <= Max ; i++ )
 {
  int k = Max - i ;
  ping HostPing = new ping ( ) ;
  //创建一个ping实例
  HostPing.ip = mask + i.ToString ( ) ;
  HostPing.ul = new UpdateList ( UpdateMyList ) ;
  //向这个ping实例中传递IP地址字符串
  mythread[k] = new Thread ( new ThreadStart ( HostPing.scan ) ) ;
  //初始化一个线程实例
  mythread[k].Start ( ) ;
  //启动线程
 }
}

  至此,【扫描网络计算机】项目已经被修改成一个多线程的程序了,此时在运行程序,并且同样再扫描上面给定IP地址区间对应的计算机,就会惊奇的发现程序执行时间所建为10秒了,并且不论要扫描的计算机数目有多少,程序的运行时间也是10秒左右,这是因为程序为扫描每一个IP都分配一个线程,这样程序的执行时间就不与要扫描的IP地址段中的IP地址数目有关联了,这样也就大大减少了程序的运行时间,提高了程序的运行效率,这也充分体现出多线程给网络编程带来的好处。图03也是程序扫描"10.138.198.1"至"10.138.198.10"这个IP地址区间计算机后的运行界面所示:


图03:基于多线程的【扫描网络计算机】项目的运行界面

  通过对二个程序的比较可见,在编写网络应用程序中,正确的使用线程的确能够大大提高程序的运行效率。

  六.总结

  至此,本节要介绍的内容就全部结束了,不知道诸位通过上面的介绍是否了解、掌握了下面几点:

  1. 如何获取系统当前时间,和实现时间日期类型数据的加减。

  2. 在编写网络应用程序时候,使用线程(多线程)的原因,以及线程(多线程)会给网络应用程序带来什么好处。

  3. 如何在应用程序中创建多个线程实例。

  4. 如何实现带"返回值"的线程。

  如果上述要点你都能够掌握,那是再好不过的了。但如果你对线程及其使用方法还感觉模糊,那也不要紧,毕竟线程在编程技术中是一个内容丰富,使用复杂的东东,要立马掌握的确是很困难的事情。在以后的文章中也将再介绍这方面的内容。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章