我有一个应用程序,它会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));
}
答案 0 :(得分:2)
答案 1 :(得分:1)
我的建议是调查你的并发点。
首先,您将通过该线程访问任何对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,而不仅仅是在最后。