【发布时间】:2015-06-13 04:22:00
【问题描述】:
我创建了一个生成多个后台工作人员的应用程序。前提是我有一个datagridview,并且有一个按钮列。
按钮列将其名称更改为“开始”和“停止”。
以下是按钮点击的代码
private void dgConfig_CellClick(object sender, DataGridViewCellEventArgs e)
{
// Ignore clicks that are not on button cells.
string row = e.RowIndex.ToString();
if (e.RowIndex < 0 || e.ColumnIndex > dgConfig.Columns[1].Index)
return;
if (e.ColumnIndex == 0 && dgConfig.Rows[e.RowIndex].Cells[0].Value.ToString().Equals("Start"))
{
dgConfig.Rows[e.RowIndex].Cells[0].Value = "Stop";
string input = string.Empty;
string output = string.Empty;
Dictionary<string, string> args = GenerateCommands(e.RowIndex);
dgConfig.Rows[e.RowIndex].Cells[0].Value.ToString());
StartThread(e.RowIndex.ToString(), "", "", args);
}
else if (e.ColumnIndex == 0 && dgConfig.Rows[e.RowIndex].Cells[0].Value.ToString().Equals("Stop"))
{
dgConfig.Rows[e.RowIndex].Cells[0].Value = "Start";
if (processes.Count > 0)
{
int procId = int.Parse(processes[e.RowIndex.ToString()]);
Process p = Process.GetProcessById(procId);
MessageBox.Show("Stopping Process "+p.ProcessName);
p.Close();
p = null;
}
}
}
这里是启动线程方法。
private void StartThread(string row, string input, string output, Dictionary<string, string> commands)
{
BackgroundWorker background = new BackgroundWorker();
background.DoWork += new DoWorkEventHandler(bkWorker_DoWork);
background.WorkerReportsProgress = false;
background.WorkerSupportsCancellation = true;
background.RunWorkerAsync(commands);
}
最后这是 Worker 进程
private void bkWorker_DoWork(object sender, DoWorkEventArgs e)
{
Dictionary<string, string> inputs = e.Argument as Dictionary<string, string>;
string newcmd = @"C:\mympeg.exe";
foreach (KeyValuePair<string, string> val in inputs )
{
newcmd += " " + val.Key + " " + val.Value;
}
Process proc = new Process();
proc.StartInfo.FileName = "cmd.exe";
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardInput = true;
proc.StartInfo.RedirectStandardError = true;
proc.OutputDataReceived += new DataReceivedEventHandler(SortOutputHandler);
proc.ErrorDataReceived += new DataReceivedEventHandler(ErrorOutputHandler);
proc.Start();
processes.Add(row, proc.Id.ToString());
if (txtLog.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate {
txtLog.AppendText("Starting Process......\r\n");
txtLog.AppendText("Command recieved: "+newcmd+"\r\n");
});
}
else
{
txtLog.AppendText("Starting Process......\r\n");
txtLog.AppendText("Command recieved: " + newcmd + "\r\n");
}
StreamWriter cmdStreamWriter = proc.StandardInput;
proc.BeginOutputReadLine();
proc.BeginErrorReadLine();
cmdStreamWriter.WriteLine(newcmd);
cmdStreamWriter.Close();
proc.WaitForExit();
if (txtLog.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate { txtLog.AppendText("\r\nFinished Process.......\r\n"); });
}
else
{
txtLog.AppendText("\r\nFinished Process.......\r\n");
}
proc.Close();
}
所以如果我启动一个长时间运行的进程,进程就会启动,我尝试挂起线程,但这不起作用。我希望能够停止特定的后台工作人员(不是全部)。
我可以在单击该行数据对应的按钮时关闭一个后台工作人员吗?
编辑
我是否可以创建一个名为 process.WaitForEvent() 的方法并将按钮单击功能传递给它?
【问题讨论】:
标签: c# multithreading winforms datagridview