我该如何填写后台工作人员的列表框



我在从后台工作线程填充列表框时遇到问题。我目前有以下代码:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var lockedUsers = new List<UserPrincipal>();
using (var context = new PrincipalContext(ContextType.Domain, "domain", smtu, smtp))
{
GroupPrincipal grp = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "Domain Users");
foreach (var userPrincipal in grp.GetMembers(false))
{
var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, userPrincipal.SamAccountName);
if (user != null)
{
if (user.IsAccountLockedOut())
{
listBox1.Items.Add(@"domain " + user);
}
}
}
}
}

这会返回一个异常,表示我无法写入主UI,这是正确的。但我一直找不到解决问题的方法。我尝试了以下方法,尽管它没有给出任何错误,但它没有填满列表框。

List<string> listusers = new List<string>();

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var lockedUsers = new List<UserPrincipal>();
using (var context = new PrincipalContext(ContextType.Domain, "domain", smtu, smtp))
{
GroupPrincipal grp = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "Domain Users");
foreach (var userPrincipal in grp.GetMembers(false))
{
var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, userPrincipal.SamAccountName);
if (user != null)
{
if (user.IsAccountLockedOut())
{
listusers.Add(@"domain" + user);
}
}
}
}
}
private async void timerlocked_Tick(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
listBox1.DataSource = listusers;
}

有什么想法吗?

传递给DoWorkEventHandler委托的DoWorkEventArgs具有Result属性

获取或设置一个表示异步操作结果的值。

您设置的Result将通过传递给该委托的RunWorkerCompletedEventArgs一起发送到RunWorkerCompleted事件。

因此,为了解决这个问题,您可以在DoWork事件内部构建一个List<string>,将Result属性设置为该列表,处理RunWorkerCompleted事件并从RunWorkerCompletedEventArgs.Result访问该列表。

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
var result = new List<string>();
var lockedUsers = new List<UserPrincipal>();
using (var context = new PrincipalContext(ContextType.Domain, "domain", smtu, smtp))
{
GroupPrincipal grp = GroupPrincipal.FindByIdentity(context, IdentityType.SamAccountName, "Domain Users");
foreach (var userPrincipal in grp.GetMembers(false))
{
var user = UserPrincipal.FindByIdentity(context, IdentityType.SamAccountName, userPrincipal.SamAccountName);
if (user != null)
{
if (user.IsAccountLockedOut())
{
result.Add(@"domain " + user);
}
}
}
}
e.Result = result;
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
// Error handling.
}
if (e.Cancelled)
{
// If you support cancellation...
}
listBox1.Items.Clear();
listBox1.Items.AddRange((e.Result as List<string>).ToArray());
}

要从后台工作线程访问UI线程,您可以在BackgroundWorkerRunWorkerCompleted事件中完成工作,或者-如果您想在工作线程运行时访问UI,请查看Control.Invoke

后面的可能是这样的:

if (user.IsAccountLockedOut())
{
listBox1.Invoke(() => listBox1.Items.Add(@"domain " + user));
}

最新更新