【问题标题】:How would I fill a ListBox from backgroundworker?我将如何从后台工作人员填充 ListBox?
【发布时间】:2019-10-29 14:01:50
【问题描述】:

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

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

有什么想法吗?

【问题讨论】:

标签: c# .net winforms listbox backgroundworker


【解决方案1】:

传递给DoWorkEventHandler 委托的DoWorkEventArgs 有一个Result property

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

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

因此,为了解决这个问题,您可以在 DoWork 事件内构建一个 List&lt;string&gt;,将 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());
}

【讨论】:

  • 感谢您的解释,它正在工作,我现在明白了!
【解决方案2】:

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

后者可能如下所示:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多