将收集从后台工作者DoWork传递给后台工作者完成并执行foreach

时间:2013-08-07 18:15:20

标签: c#

我的目标是:

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

我的错误发生在我的backgroundWorker_RunWorkerCompleted方法的foreach循环中。

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

如果我做一个MessageBox.Show(results.First()。ToString());在DoWork方法中,我可以查看集合中的第一个计算机名称。 (如果收集是正确的术语,请原谅我)

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

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

我刚刚在一个月前拿到了C#,我来自PowerShell所以如果我使用了错误的词汇,我会提前道歉。这对我来说都很新鲜。

非常感谢任何关于此的指导!

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

2 个答案:

答案 0 :(得分:1)

您应该将对象强制转换为IEnumerable或您知道的类型

  var collection = (PrincipalSearchResult<Principal>) e.Result;
  foreach (var PC in collection) 
    {
        comboBox1.Items.Add(PC.ToString());
    }     

答案 1 :(得分:1)

您必须将e.Result中的object转换为PrincipalSearchResult<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

编辑:

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