c#在foreach循环期间暂停,直到process . exit

本文关键字:直到 process exit 暂停 foreach 循环 | 更新日期: 2023-09-27 18:07:43

我有一个foreach循环通过一个DataGridView。对于网格中的每一行,它执行pspasswrd.exe并更改本地帐户的密码。如何暂停foreach循环,直到进程完成,然后再移动到列表中的下一台计算机?

我不确定,我试过WaitForExit,但这是不可靠的,因为它是同步的,所以它会导致我的程序不响应,如果它需要很长时间。我需要使用Process。退出,但不确定如何正确执行

这是我的foreach循环。它还检查密码是否更改成功。如果成功,将数据输入到另一个Datagridview。
foreach (DataGridViewRow row in dgvData.Rows)
        {
            if (!row.IsNewRow && row.Cells["cIPAddress"].Value.ToString().Contains("Invalid") == false)
            {
                if (pspasswrd(row.Cells["cIPAddress"].Value.ToString(), tbTargetUser.Text, NewPassword).Contains("Password successfully changed"))
                {
                    dgvResults.Rows.Add(row.Cells["cIPAddress"].Value.ToString(), tbTargetUser.Text, NewPassword);
                    AppendNumber = AppendNumber + IncreaseNumber;
                    NewPassword = BasePassword + AppendNumber;
                }
                else
                    row.DefaultCellStyle.BackColor = Color.Red;
            }
            Thread.Sleep(1000);
        }

但我不确定的是,如果我改变我的代码下面使用process.exit。它将如何将密码更改与成功登录的计算机关联起来。因为它将是异步的。

public string pspasswrd(string ip, string user, string password)
    {
        String CD = @Directory.GetCurrentDirectory() + "''pspasswrd.exe";
        ProcessStartInfo p = new ProcessStartInfo();
        string result = null;
        p.FileName = CD;
        p.Arguments = @"''" + ip + " " + user + " " + password + " -accepteula";
        p.CreateNoWindow = true;
        p.RedirectStandardOutput = true;
        p.RedirectStandardError = true;
        p.UseShellExecute = false;
        Process x = Process.Start(p);
        StreamReader stream = x.StandardOutput;
        result = stream.ReadToEnd();
        x.WaitForExit(2000);
        x.Close();
        return result;
    }

c#在foreach循环期间暂停,直到process . exit

你应该首先从DataGridView收集所有需要的信息,然后在后台线程循环收集而不是DataGridView中运行执行pspasswrd.exe的代码,并使用WaitForExit,这不会阻塞你的UI线程。

编辑

下面是带有WaitForExit和一个新线程的代码。我相信使用Exit事件而不是WaitForExit将不会获得太多好处,除了更复杂和死锁的场景:
 private void OnSomeUIEvent()
    {
        //In UI thread
        var ipRows = new Dictionary<string, DataGridViewRow>();
        var targetUser = ""; //tbTargetUser.Text
        var pwd = ""; //NewPassword
        var basePassword = ""; //Some value
        foreach (DataGridViewRow row in dgvData.Rows)
        {
            var ipAddress = row.Cells["cIPAddress"].Value.ToString();
            if (!row.IsNewRow && ipAddress.Contains("Invalid") == false)
            {
                ipRows.Add(ipAddress, row);
            }
        }
        Task.Factory.StartNew(() => {
            ChangePassword(ipRows, targetUser, pwd, basePassword);
        }).ContinueWith(t => { 
           //Do Something when task completed
        });
    }
    private void ChangePassword(Dictionary<string, DataGridViewRow> ipRows, string targetUser, string newPwd, string basePwd)
    {  //in background thread
        foreach (var ipRow in ipRows)
        {
            var pwd = newPwd;
            var basePassword = basePwd;
            var appendNumber = 0;
            var increaseNumber = 1; //some number
            if (pspasswrd(ipRow.Key, targetUser, pwd).Contains("Password successfully changed"))
            {
                dgvResults.Invoke((MethodInvoker)(() =>
                {
                    dgvResults.Rows.Add(ipRow.Key, targetUser, pwd);
                }));
                appendNumber = appendNumber + increaseNumber;
                pwd = basePassword + increaseNumber;
            }
            else
            {
                dgvData.Invoke((MethodInvoker)(() =>
                {
                    ipRow.Value.DefaultCellStyle.BackColor = Color.Red;
                }));
            }
        }
    }