2010-07-20 43 views
2

我想從一個大局域網中獲取活着或死亡的IP地址。但需要很多次。我決定在這裏使用的BackgroundWorker是我的代碼:通過背景工作控制在局域網上獲取IP地址

try 
{ 

    this.Status.Text = "Collecting Information..."; 

    if(this.TxtWorkGroup.Text.Trim() == "") 
    { 
     MessageBox.Show("The Work Group name Should Not be Empty"); 
     return; 
    } 


    // Use Your work Group WinNT://&&&&(Work Group Name) 
    DirectoryEntry DomainEntry = new DirectoryEntry("WinNT://" + this.TxtWorkGroup.Text.Trim()); 
    DomainEntry.Children.SchemaFilter.Add("computer"); 


    // To Get all the System names And Display with the Ip Address 
    foreach(DirectoryEntry machine in DomainEntry.Children) 
    { 
     string[] Ipaddr = new string[3]; 
     Ipaddr[0] = machine.Name; 


     System.Net.IPHostEntry Tempaddr = null; 

     try 
     { 
      Tempaddr = (System.Net.IPHostEntry)Dns.GetHostByName(machine.Name); 
     } 
     catch(Exception) 
     { 
      //MessageBox.Show("Unable to connect woth the system :" + machine.Name); 
         deadHostList.Items.Add(machine.Name); 
      continue; 
     } 
     System.Net.IPAddress[] TempAd = Tempaddr.AddressList; 
     foreach(IPAddress TempA in TempAd) 
     { 
      Ipaddr[1] = TempA.ToString(); 

      byte[] ab = new byte[6]; 
      int len = ab.Length; 

      // This Function Used to Get The Physical Address 
      int r = SendARP((int) TempA.Address, 0, ab, ref len); 
      string mac = BitConverter.ToString(ab, 0, 6); 

      Ipaddr[2] = mac; 
     }   

     System.Windows.Forms.ListViewItem TempItem = new ListViewItem(Ipaddr); 

     this.ListHostIP.Items.Add(TempItem); 
    } 

    this.Status.Text = "Displayed"; 
} 
catch(Exception ex) 
{ 
    MessageBox.Show(ex.Message,"Error",System.Windows.Forms.MessageBoxButtons.OK ); 
    Application.Exit(); 
} 

但是當我嘗試在backgroundWorker1_DoWork事件使用這些代碼它給我的錯誤信息

跨線程操作無效:控制「deadHostList」從其創建的線程以外的線程訪問

如何修改我的代碼?

回答

2

由於克里斯和裏德說....你只能從線程修改UI控件,該控件上創建...

您還可以使用的BackgroundWorker的ProgressChanged事件的UI更新... 。

var worker = new BackgroundWorker() 
    { 
    WorkerReportsProgress = true, 
    WorkerSupportsCancellation = true 
    }; 

    /// runs on background thread 
    worker.DoWork += (s, e) => 
    { 
    while (!done) 
    { 
     DoSomeWork(); 
     // send a message to the Ui 
     // via the ProgressChanged event 
     worker.ReportProgress(percent, statusMessage); 
    } 
    }; 

    /// the ProgressChanged event runs on the UI thread 
    worker.ProgressChanged += (s, e) => 
    { 
    var msg = (MyStatusMessage)e.UserState; 
    someUiControl.Items.Add(msg.Text); 
    }; 

    /// also runs on Ui thread 
    worker.RunWorkerCompleted += (s, e) => 
    { 

    }; 

    worker.RunWorkerAsync(); 
+0

感謝您的回答。我明白要在worker.ProgressChanged事件中獲取我的記錄。我會嘗試這個 但我想使用多線程,因爲我的網絡中有1000多臺計算機的模式。我可以用背景工作嗎? – Rapunzo 2010-07-21 08:08:25

2

您不能也不應該從創建控件的線程以外的任何線程訪問UI控件。我想你的deadHostList是一個ListView控件或類似的東西。

您可以通過使用Control.InvokeControl.BeginInvoke

0

元帥從後臺線程到UI線程的請求,你需要總是元帥調用UI元素,比如你的列表控件,到UI線程。

您可以通過Control.Invoke做到這一點。更改此:

deadHostList.Items.Add(machine.Name); 

要:

string name = machine.Name; 
deadHostList.Invoke(new Action(() => deadHostList.Items.Add(name))); 

您還需要以後做同樣的事情ListHostIP - 確保使用Control.Invoke來包裝調用爲好。