线程安全/调用方法导致StackOverflowException

时间:2018-03-09 16:06:09

标签: c# thread-safety invoke

这是一个使用WMI在远程计算机上获取本地管理员组成员的应用程序。为了尝试从后台工作器中进行线程安全调用来更新我的主UI,我得到了一个StackOverflowException。我已经从Stack上的另一个线程复制了这个例子。有人可以帮我确定原因吗?

private void getLocalAdministrators(string serverName)
    {
        try
        {
            System.Management.ManagementScope scope = new System.Management.ManagementScope("\\\\" + serverName + "\\root\\cimv2");
            scope.Connect();

            StringBuilder qs = new StringBuilder();
            qs.Append("SELECT PartComponent FROM Win32_GroupUser WHERE GroupComponent = \"Win32_Group.Domain='" + serverName + "',Name='" + "Administrators'\"");

            System.Management.ObjectQuery query = new System.Management.ObjectQuery(qs.ToString());
            System.Management.ManagementObjectSearcher searcher = new System.Management.ManagementObjectSearcher(scope, query);

            foreach (System.Management.ManagementObject group in searcher.Get())
            {
                string groupDetails = serverName + tab + group["PartComponent"].ToString() + tab;

                string domainPart = groupDetails.Split('=')[1];
                domainPart = domainPart.Replace("\"","").Replace(",Name","");

                string accountPart = groupDetails.Split('=')[2];
                accountPart = accountPart.Replace("\"", "");

                if (query != null)
                {
                    updateUISafely(serverName + tab + domainPart + tab + accountPart);
                }
                else
                {
                    updateUISafely("Error with: " + serverName);
                }
            }
        }
        catch (Exception ex)
        {
            updateUISafely("Error with: " + serverName + ". " + ex.Message);
        }

    }

    public delegate void ProcessResultDelegate(string result);
    void updateUISafely(string result)
    {
        if (textBox2.InvokeRequired)
        {
            var d = new ProcessResultDelegate(updateUISafely);
            d.Invoke(result);
        }
        else
        {
            textBox2.AppendText(result + nl);
        }
    }


    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        string[] strArray;
        strArray = textBox1.Text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);

        int objectCount = strArray.Count();
        int count = 0;

        foreach (string str in strArray)
        {
            getLocalAdministrators(str);
            count++;
            backgroundWorker1.ReportProgress((100 * count) / objectCount);
        }
    }

    private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        progressBar1.Value = e.ProgressPercentage;
    }

    private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
        foreach (string item in resultsList)
        {
            textBox2.AppendText(item + Environment.NewLine);
        }
        btnGet.Enabled = true;
    }

1 个答案:

答案 0 :(得分:0)

您正在调用(也就是调用)委托,导致它重复调用updateUISafely而无需调用UI线程。

您应该在表单/控件上调用Invoke,而不是将委托作为参数。

使用:

this.Invoke(d);