我希望从一个大局域中获得活着或死亡的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”
如何修改我的代码?
答案 0 :(得分:2)
您不能也不应该从创建控件的线程以外的任何线程访问UI控件。我猜你的deadHostList是一个ListView控件或类似的东西。
将后台线程中的请求封送到UI线程答案 1 :(得分: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();
答案 2 :(得分:0)
您需要始终将对UI元素的调用(例如列表控件)封送到UI线程上。
您可以通过Control.Invoke执行此操作。改变这个:
deadHostList.Items.Add(machine.Name);
要:
string name = machine.Name;
deadHostList.Invoke(new Action( () => deadHostList.Items.Add(name)));
您还需要稍后为ListHostIP
执行相同的操作 - 确保使用Control.Invoke
来包装该调用。