Com*_*ser 7 c# asp.net multithreading process
我运行一个进程,在命令行中使用参数执行exe,并且需要一些时间才能完成.在此期间,我将表单显示为带有进度条和取消按钮的对话框.按下取消按钮时,该过程应该中止/停止.我有两种方法可以做到:
A.在主窗体中声明Process类的公共静态对象,并在单击取消按钮时从进度窗体中止它:
public partial class frmMain : Form
{
public static Process Process = new Process();
public static bool ExecuteCommand(string sCommandLineFile, string sArguments)
{
Process.StartInfo.FileName = sCommandLineFile;
Process.StartInfo.Arguments = sArguments;
Process.StartInfo.CreateNoWindow = true;
Process.StartInfo.UseShellExecute = false;
Process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
Process.Start();
Process.WaitForExit();
}
}
Run Code Online (Sandbox Code Playgroud)
从Progress窗口表单中关闭/中止进程:
public partial class frmProgress : Form
{
private void btnCancel_Click(object sender, EventArgs e)
{
frmMain.Process.Close();
frmMain.Process.Dispose();
}
}
Run Code Online (Sandbox Code Playgroud)
B.或者不要调用Process.WaitForExit(); 而是使用Process.HasExited来检查进程是否正在运行,如果单击取消按钮则取消它:
public static bool IsCancelled = false;
Process.StartInfo.FileName = sCommandLineFile;
Process.StartInfo.Arguments = sArguments;
Process.StartInfo.CreateNoWindow = true;
Process.StartInfo.UseShellExecute = false;
Process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
while (!Process.HasExited)
{
Thread.Sleep(100);
Application.DoEvents();
if (IsCancelled)
{
Process.Close();
Process.Dispose();
}
}
public partial class frmProgress : Form
{
private void btnCancel_Click(object sender, EventArgs e)
{
frmMain.IsCancelled = true;
}
}
Run Code Online (Sandbox Code Playgroud)
做正确的方法是什么?
A mix of the two.
public partial class frmMain : Form
{
public static Process Process = new Process();
public static bool ExecuteCommand(string sCommandLineFile, string sArguments)
{
Process.StartInfo.FileName = sCommandLineFile;
Process.StartInfo.Arguments = sArguments;
Process.StartInfo.CreateNoWindow = true;
Process.StartInfo.UseShellExecute = false;
Process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
Process.Start();
// Process.WaitForExit(); // Don't wait here, you want the application to be responsive
}
}
Run Code Online (Sandbox Code Playgroud)
And in the cancel handler
private void btnCancel_Click(object sender, EventArgs e)
{
frmMain.Process.Close(); // or .Kill()
frmMain.Process.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
Of course now you need a way of finding whether the process has exited the normal way. Use Process.HasExited regularly to poll for termination. Best to use a timer for this. I'm not currently sure, but there might even be an event for this.
Your second solution has the problem that it is actively waiting for the process to finish while still blocking the user interface. And it is using Application.DoEvents() which you should avoid by all means because it creates all kinds of nasty side effects (for instance you will be able to have the same code run several times in a recursion).
| 归档时间: |
|
| 查看次数: |
6789 次 |
| 最近记录: |