2010-01-22 57 views
6

我有一個應用程序,可以在本地子網上ping每個可能的IP,以編譯響應IP地址列表。目前它一次只顯示255個。是否有可能轉換此應用程序使用多個線程來增加速度,通過一次ping多個?我是新來的多線程的概念,並認爲這將是一個很好的學習方式(只要有可能)。將Ping應用程序轉換爲多線程版本以提高速度 - C#

另外,你可以教我的任何風格改進也是有幫助的。提前

由於這裏處於backgroundWorker1_DoWork事件中的當前爆震的方法。

 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)); 

    } 

回答

2

看起來Ping具有SendAsync函數。 This後(我知道它的vb,但只是爲了得到一個想法)有一個例子。總之,只要改變你的發送SendAsync並聽取PingCompleted事件

1

那麼我的建議是看看你的併發點。

首先,你會遇到任何訪問線程窗口對象的bug。即您對button1的訪問將在調試中拋出MDA,並可能在運行時隨機崩潰。您必須使用委託並使用這樣的模式在主線程上調用該方法。其次,你的時間花在了ping本身上。因此,我建議寫一個線程列表(只寫一個方法上有一個鎖

private object locker = new object(); 

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

我會建議使用.net線程池來運行你的方法,而不是來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); 

其中方法是ping方法,obj包含一個包含manualresetevent的對象以及您的方法需要ping其目標的信息。

每次您的等待句柄完成後,您都可以更新狀態。通過在GUI上進行更多的努力,你甚至可以讓系統異步工作,這樣你的GUI就會在每個響應中更新,而不僅僅是最後。

+0

我敢肯定,這是完全合理的,我只是不知道它說什麼,哈哈。對不起,如果我是補救,這個解決方案是在我的頭上,這可能意味着我的問題也在我的頭上。 – user48202 2010-01-22 02:16:25

+0

如何在調用此方法時傳遞參數ipList.Invoke(new MethodInvoker(UpdateIpList(lineBuffer)));它不斷告訴我「UpdateIpList(lineBuffer)」不是一種方法。 – user48202 2010-01-22 02:55:47

+0

Windows窗體和線程並不容易。同時發生併發的事情,需要一點學習才能做到。我強烈推薦「Visual C#2008編程基礎類庫」,它有很好的線程介紹(以及框架的所有好的部分)。 – Spence 2010-01-22 03:13:11

相關問題