将Ping应用程序转换为multithreading版本以提高速度 – C#

我有一个应用程序,它会ping本地子网上的每个可能的IP,以便编译响应的IP地址列表。 目前,它一次ping所有255个。 是否可以将此应用程序转换为使用多个线程来通过一次ping多个来提高速度? 我是multithreading概念的新手,并认为这是一个很好的学习方法(只要当然可能)。

此外,您可以教育我的任何风格改进也会有所帮助。

提前谢谢

这是backgroundWorker1_DoWork事件中的当前ping方法。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { count = 0; for (int i = 1; i < 255; i++) { Ping ping = new Ping(); PingReply pingreply = ping.Send(IPAddress.Parse(locip[0] + "." + locip[1] + "." + locip[2] + "." + i)); count += 1; if (pingreply.Status == IPStatus.Success) { status = "o"; repAddress = pingreply.Address.ToString(); ; repRoundtrip = pingreply.RoundtripTime.ToString(); repTTL = pingreply.Options.Ttl.ToString(); repBuffer = pingreply.Buffer.Length.ToString(); string[] lineBuffer = { status, repAddress, repRoundtrip, repTTL, repBuffer }; ipList.Rows.Add(lineBuffer); } progressBar.Invoke(new MethodInvoker(UpdateProgressBarByOne)); progressStatus.Text = ("Pinging IP " + count + " of 254"); } button1.Enabled = true; progressBar.Invoke(new MethodInvoker(ResetProgressBar)); } 

看起来Ping具有SendAsyncfunction。 这篇文章(我知道它的vb,但只是为了得到一个想法)有一个例子。 总之,只需更改Send to SendAsync并监听PingCompleted事件即可

我的建议是调查你的并发点。

首先,您将在线程中访问任何对Windows窗体对象的访问时遇到错误。 即,您对button1的访问将在调试中抛出MDA,并可能在运行时随机崩溃。 您必须使用委托并使用这样的模式在主线程上重新调用该方法。

 this.Invoke(delgatetomyupdatermethod) 

其次,你的时间花在ping本身上。 所以我建议编写一个线程安全列表(只需编写一个带锁的方法)

 private object locker = new object(); private void InsertIntoList(string linebuffer) { lock(locker) { ipList.Rows.Add(linebuffer); } } 

我建议使用.Net threadpool来运行你的方法来ping一个给定的IP。

要执行此操作,请编写一个函数,该函数将接受IP以进行ping并使用您的结果更新列表,然后通过对线程池中的项目进行排队来调用它。 实际上,如果您使用ManualResetEvent传入一个对象,您甚至可以编写代码来说明

 System.Threading.WaitHandle[] waits = new System.Threading.WaitHandle[255]; //initialise the list of these and create the objects to ping. foreach (var obj in mylistofobjectvalues) { System.Threading.Threadpool.QueueUserWorkItem(method, obj); } System.Threading.WaitHandle.WaitAll(waits); 

其中method是ping方法,obj包含一个带有manualresetevent的对象和你的方法需要ping它的目标的信息。

每次等待处理完成后,您都可以更新您的状态。 通过GUI的更多工作,您甚至可以让系统异步工作,这样您的gui就会在每个响应上更新,而不仅仅是在最后。