Получите IP-адреса на локальной сети с контролем фонового работника - PullRequest
2 голосов
/ 20 июля 2010

Я хочу получить живые или мертвые IP-адреса с большой локальной сети. но это занимает так много раз. Я решил использовать backgroundworker вот мой код:

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' доступен из потока, отличного от потока, в котором он был создан

Как мне изменить мои коды?

Ответы [ 3 ]

2 голосов
/ 20 июля 2010

Как заявили Крис и Рид .... вы можете изменять элемент управления Ui только из потока, в котором он был создан ...

Вы также можете использовать событие BackgroundWorker's ProgressChanged для обновлений пользовательского интерфейса ....

  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();
2 голосов
/ 20 июля 2010

Вы не можете и не должны получать доступ к элементам управления пользовательского интерфейса из любого потока, кроме потока, который создал элемент управления. Я предполагаю, что ваш deadHostList - это элемент управления ListView или что-то подобное.

Вы можете направить запрос из фонового потока в поток пользовательского интерфейса, используя Control.Invoke или Control.BeginInvoke

0 голосов
/ 20 июля 2010

Вам необходимо всегда маршалировать вызовы элементов пользовательского интерфейса, таких как элемент управления списком, в поток пользовательского интерфейса.

Вы можете сделать это через Control.Invoke. Изменить это:

deadHostList.Items.Add(machine.Name);

Кому:

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

Вы также должны будете сделать то же самое позже для ListHostIP - обязательно используйте Control.Invoke, чтобы обернуть этот вызов.

...