所以我有一个遍历DataGridView的foreach循环。对于网格中的每一行,它执行pspasswrd.exe并更改本地帐户的密码。在进入列表中的下一台计算机之前,如何暂停foreach循环直到进程完成?
我不确定,我尝试了WaitForExit,但这不可靠,因为它是同步的,所以如果需要很长时间,它会导致程序无法响应。我需要利用Process.Exited但不确定如何正确地执行此操作。
这是我的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.exited。它如何将密码更改与其成功运行的计算机相关联。因为它将是异步的。
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;
}
答案 0 :(得分:1)
您应首先从集合中的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;
}));
}
}
}