【问题标题】:Get ip adresses on a lan with backgroundworker control使用后台工作人员控制获取局域网上的 IP 地址
【发布时间】:2010-07-20 18:23:46
【问题描述】:

我想从一个大局域网中获取有效或无效的 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”从创建它的线程以外的线程访问

如何修改我的代码?

【问题讨论】:

    标签: c# multithreading network-programming backgroundworker


    【解决方案1】:

    正如 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();
    

    【讨论】:

    • 感谢您的回答。我了解在 worker.ProgressChanged 事件中获取我的记录。我会试试这个,但我想使用多线程,因为我的网络中有超过 1000 台计算机的模式。我可以用 backgroundworker 做点什么吗?
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      您可以通过 Control.Invoke 执行此操作。改变这个:

      deadHostList.Items.Add(machine.Name);
      

      收件人:

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

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

      【讨论】:

        猜你喜欢
        • 2012-01-10
        • 1970-01-01
        • 1970-01-01
        • 2015-01-31
        • 1970-01-01
        • 2016-02-26
        • 2011-12-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多