将 Ping 应用程序转换为多线程版本以提高速度 - C#
我有一个应用程序,可以 ping 本地子网上的每个可能的 IP,以便编译响应 IP 地址的列表。目前它一次 ping 全部 255 个。是否可以将此应用程序转换为使用多个线程,通过一次 ping 多个线程来提高速度?我对多线程的概念很陌生,并认为这将是一种很好的学习方法(当然只要可能)。
另外,您可以教育我的任何风格改进也会很有帮助。
提前致谢
这是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));
}
I have an application that pings every possible IP on your local subnet in order to compile a list of responsive IP addresses. Currently it pings all 255 one at a time. Is it possible to convert this app to use multiple threads to increase the speed by pinging more than one at a time? I am new to the concept of multiple threads and figure this would be a good way to learn(as long as it's possible of course).
also, any stylistic improvements you can educate me on would also be helpful.
thanks ahead of time
Here is the current pinging method in a backgroundWorker1_DoWork event.
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));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看起来 Ping 有一个 SendAsync 功能。 这篇帖子(我知道它的vb,但只是为了了解一下)一个例子。总之,只需将 Send 更改为 SendAsync 并监听 PingCompleted 事件
It looks like Ping has a SendAsync function. This post (I know its vb, but just to get an idea) has an example. In summary, just change your Send to SendAsync and listen for the PingCompleted event
嗯,我的建议是调查一下你的并发点。
首先,您将在线程之外访问 Windows 窗体对象时遇到错误。即您对button1的访问将在调试中引发MDA,并且可能在运行时随机崩溃。您必须使用委托并使用这样的模式在主线程上调用该方法。
其次,您的时间花在 ping 本身上。因此,我建议编写一个线程安全列表(只需编写一个带有锁的方法,
我建议使用 .Net 线程池来运行您的方法,而不是 ping 给定的 IP。
为此,请编写一个函数,该函数将接收 IP ping 并用结果更新列表,然后通过在线程池上排队项目来调用它。事实上,如果您使用 ManualResetEvent 传入一个对象,您甚至可以编写代码来说明
其中 method 是 ping 方法,obj 包含一个对象。通过手动重置事件和您的方法需要 ping 其目标的信息,
每次等待处理完成时,您都可以更新您的状态,通过在 GUI 上做更多的努力,您甚至可以让系统异步工作,以便您的 gui 在每次响应时更新。不只是在最后。
Well my advice is to look into your concurrency points.
Firstly you will hit a bug with any access to windows forms objects off the thread. i.e your access to button1 WILL throw an MDA in debug, and might crash at runtime randomly. You have to use a delegate and invoke the method back on the main thread using a pattern like this.
Secondly, your time is spent in the ping itself. So I would recommend writing a threadsafe list (just write a method with a lock on it
I would recommend using the .Net threadpool to run your method instead to ping a given IP.
To do this write a function that will take in the IP to ping and to update the list with your result, then call it by queueing up items on the threadpool. Indeed if you pass in an object with a ManualResetEvent you can even write your code to say
where method is the ping method, obj contains an object with the manualresetevent and information your method needs to ping it's target.
Each time your waithandle completes you can update your state. With some more effort on your GUI you could even have the system working asynchronously, so that your gui is updated on each response, not just at the end.