c# - 将集合从后台工作程序 DoWork 传递到后台工作程序已完成并执行 foreach

标签 c#

我的目标是:

  • 用户在组合框中输入完整或部分计算机名
  • 按钮单击事件启动后台工作人员将计算机名传递给 DoWork 方法
  • DoWork 方法在 ActiveDirectory 中搜索计算机名并将集合传递给 WorkerCompleted 方法
  • WorkerCompleted 方法将每个计算机名称添加到组合框项目中。

我的错误出现在backgroundWorker_RunWorkerCompleted 方法中的foreach 循环处。

  • “foreach 语句无法对“object”类型的变量进行操作,因为“object”不包含“GetEnumerator”的公共(public)定义”

如果我执行 MessageBox.Show(results.First().ToString());在 DoWork 方法中,我可以查看集合中的第一台计算机名称。

如果我执行 MessageBox.Show(e.Result.ToString());在 DoWork 和 WorkerCompleted 方法中,我得到这个:

  • “System.DirectoryServices.AccountManagement.PrincipalSearchResult`1[System.DirectoryServices.AccountManagement.Principal]”

对此的任何指导将不胜感激!

    private void button1_Click(object sender, EventArgs e)
    {
        //Saves computername entered by user to pass into DoWork method
        string PCName = comboBox1.Text;

        //Start background thread passing computer to the Dowork method
        backgroundWorker1.RunWorkerAsync(PCName);
    }
   
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {                 
        using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain))
        {
            //Setup Filter
            ComputerPrincipal computer = new ComputerPrincipal(ctx);
            computer.Name = "*" + e.Argument + "*";

            //Search for PC
            PrincipalSearcher ps = new PrincipalSearcher();
            ps.QueryFilter = computer;

            //Get Results
            PrincipalSearchResult<Principal> results = ps.FindAll();
                 
            //results will be passed to RunWorkerCompleted
            e.Result = results;                
        }
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        //Add each computername to combobox
        foreach (object PC in e.Result) // <--------------- ERROR HERE!
        {
            comboBox1.Items.Add(PC.ToString());
        }                            
    }
}

最佳答案

您必须转换e.Result在已完成的处理程序中 objectPrincipalSearchResult<Principal>以便迭代它。

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    //Add each computername to combobox
    PrincipalSearchResult<Principal> results = (PrincipalSearchResult<Principal>)e.Result;
    foreach (Principal PC in results)
    {
        comboBox1.Items.Add(PC.ToString());
    }                            
}

编辑:

PrincipalSearcher不能在后台工作程序中使用,因为它使用需要单线程单元(STA)的COM组件。后台工作线程在多线程单元 (MTA) 中运行。 ApartmentState 可以使用 Thread.SetApartmentState 设置,但必须在线程启动之前调用(因此不能用于更改BackgroundWorker工作线程的ApartmentState)。

关于c# - 将集合从后台工作程序 DoWork 传递到后台工作程序已完成并执行 foreach,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18110738/

相关文章:

c# - iTextSharp - 绝对坐标表

c# - ASP.NET WebAPI 2 + Entity Framework 连接缓存最佳实践

c# - 位图无法将文件保存到刚刚以编程方式创建的目录

C# listview imagelist 快速添加多个项目

c# - Entity Framework 到 json - 分组数据

c# - 使用NServiceBus时,MVVM中的ObservableCollection不变

c# - 以人类可读的文本格式序列化

c# - 如何获取 guest /管理员的本地组名?

c# - EF即使附加了父级也插入重复行

c# - 如何在 MongoDB C# 驱动程序中按字段值范围选择文档?