将集合从backgroundworkerDoWork传递给backgroundworker Completed并执行fo

本文关键字:Completed backgroundworker 执行 fo 集合 backgroundworkerDoWork | 更新日期: 2023-09-27 18:26:43

我的目标是:

  • 用户在组合框中键入完整或部分计算机名
  • 按钮单击事件启动后台工作程序,将计算机名传递给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.PrinipalSearchResult`1[System.DirectoryServices.AccountManager.Prinipar]"

如有任何指导,我们将不胜感激!

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

将集合从backgroundworkerDoWork传递给backgroundworker Completed并执行fo

您必须将Completed处理程序中的e.Resultobject强制转换为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不能在后台工作程序中使用,因为它使用了需要单线程单元(STA)的COM组件。后台工作线程在多线程单元(MTA)中运行。ApartmentState可以使用Thread.SetApartmentState设置,但必须在线程启动前调用它(因此不能用于更改BackgroundWorker工作线程的ApartmentState)。

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

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