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;
}
你应该首先从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;
}));
}
}
}