我将如何从 backgroundworker 中填充 ListBox?
How would I fill a ListBox from backgroundworker?
我在从后台工作线程填充列表框时遇到问题。我目前有以下代码:
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);
}
}
}
}
}
这个 returns 异常说我不能写主 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;
}
有什么想法吗?
要从后台工作者访问 UI 线程,您可以在 RunWorkerCompleted
event of the BackgroundWorker
or - if you want to access the UI while the worker is running, have a look at Control.Invoke
中完成工作。
后者可能是这样的:
if (user.IsAccountLockedOut())
{
listBox1.Invoke(() => listBox1.Items.Add(@"domain\ " + user));
}
传递给 DoWorkEventHandler
委托的 DoWorkEventArgs
有一个 Result
property
Gets or sets a value that represents the result of an asynchronous operation.
您设置的 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());
}
我在从后台工作线程填充列表框时遇到问题。我目前有以下代码:
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);
}
}
}
}
}
这个 returns 异常说我不能写主 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;
}
有什么想法吗?
要从后台工作者访问 UI 线程,您可以在 RunWorkerCompleted
event of the BackgroundWorker
or - if you want to access the UI while the worker is running, have a look at Control.Invoke
中完成工作。
后者可能是这样的:
if (user.IsAccountLockedOut())
{
listBox1.Invoke(() => listBox1.Items.Add(@"domain\ " + user));
}
传递给 DoWorkEventHandler
委托的 DoWorkEventArgs
有一个 Result
property
Gets or sets a value that represents the result of an asynchronous operation.
您设置的 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());
}