通过后台工作者控制获取局域网上的 IP 地址

发布于 2024-09-10 19:44:53 字数 2040 浏览 5 评论 0原文

我想从一个大的 LAN 中获取活跃或无效的 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”

如何修改我的代码?

I want to get alive or dead ip addresses from a big lan. but it takes so many times. I decided to use backgroundworker here is my code:

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

but when I try to use these codes in backgroundWorker1_DoWork event it gives me error messages

Cross-thread operation not valid: Control 'deadHostList' accessed from a thread other than the thread it was created on

How can I modify my codes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

高速公鹿 2024-09-17 19:45:01

您需要始终将对 UI 元素(例如列表控件)的调用封送到 UI 线程上。

您可以通过 Control.Invoke 来完成此操作。将其更改

deadHostList.Items.Add(machine.Name);

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

:稍后您还需要对 ListHostIP 执行相同的操作 - 确保也使用 Control.Invoke 来包装该调用。

You need to always marshal calls to UI elements, such as your list control, onto the UI thread.

You can do this via Control.Invoke. Change this:

deadHostList.Items.Add(machine.Name);

To:

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

You'll also need to do the same thing later for ListHostIP - make sure to use Control.Invoke to wrap that call as well.

舟遥客 2024-09-17 19:44:59

您不能也不应该从创建控件的线程以外的任何线程访问 UI 控件。我猜你的 deadHostList 是一个 ListView 控件或类似的东西。

您可以使用 Control.Invoke 将请求从后台线程编组到 UI 线程Control.BeginInvoke

You cannot and should not access UI controls from any thread other than the thread that created the control. I guess your deadHostList is a ListView control or something similar.

You can marshal a request from the background thread to the UI thread by using Control.Invoke or Control.BeginInvoke

机场等船 2024-09-17 19:44:58

正如 Chris 和 Reed 所说...您只能从创建控件的线程中修改 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();

As Chris and Reed stated....you can only modify a Ui control from the thread that the control was created on...

You can also use the BackgroundWorker's ProgressChanged event for Ui updates....

  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();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文