我的表单包含两个控件:button1和timer1
timer1.Interval=1000; timer1.Enable=true;
单击button1时,将启动Windows上的应用程序。例如:记事本会显示。
但是当记事本显示时,timer1没有运行
如何使timer1这样运行?
我的代码:
private void button1_Click(object sender, EventArgs e)
{
Process pro = new Process();
pro.StartInfo.FileName = "notepad";
pro.StartInfo.Arguments = "";
pro.Start();
pro.WaitForExit();
}
private void timer1_Tick(object sender, EventArgs e)
{
DateTime dtime = DateTime.Now;
string date_time = dtime.ToString("dd/MM/yyyy HH:mm:ss");
textBox2.Text = date_time;
}
答案 0 :(得分:4)
指示Process组件无限期等待以使相关进程退出。
您的计时器正在尝试调用timer1_Tick
,但您的UI线程目前仍在等待进程退出,但它不会。
您有两种选择来解决这个问题:
WaitForExit
的调用Process.EnableRaisingEvents
设置为true
并注册Process.Exited
活动答案 1 :(得分:1)
pro.WaitForExit();
使UI线程冻结,因此无法更新。
要阻止用户执行操作,您可以在进程运行时禁用某些控件。当用户关闭流程时,您可以订阅process.Exited
事件并启用控件。
private void button1_Click(object sender, EventArgs e)
{
Process pro = new Process();
pro.StartInfo.FileName = "notepad";
pro.StartInfo.Arguments = "";
pro.Start();
button1.Enabled = false;
pro.EnableRaisingEvents = true;
pro.Exited += pro_Exited;
}
void pro_Exited(object sender, EventArgs e)
{
button1.Invoke((MethodInvoker) delegate { button1.Enabled = true; });
}
<强>更新强>
如另一个答案所示,您应将EnableRaisingEvents
属性设置为true
。
另外pro_Exited
方法将在不同的线程中运行,因此您需要使用Control.Invoke
方法来更改UI。
更新2
如果无法删除pro.WaitForExit();
,则可以使用其他计时器,因为System.Windows.Forms.Timer
正在UI线程中运行并被其阻止。
private System.Threading.Timer timer = new System.Threading.Timer(Callback);
public Form()
{
InitializeComponent();
timer.Change(0, 1000);
}
private void Callback(object state)
{
DateTime dtime = DateTime.Now;
string date_time = dtime.ToString("dd/MM/yyyy HH:mm:ss");
button1.Invoke((MethodInvoker)delegate { textBox1.Text = date_time; });
}
当textBox
打开时,它不会更新process
,但计时器将会运行并且可以完成一些工作。
更新3
如果是多个流程,您可以对它们进行计数,并在pro_Exited
方法中检查活动流程的数量。
private volatile int activeProcessCount = 0;
private void pro_Exited(object sender, EventArgs e)
{
activeProcessCount--;
if (activeProcessCount == 0)
{
button1.Invoke((MethodInvoker) delegate { button1.Enabled = true; });
}
}
private void button1_Click(object sender, EventArgs e)
{
//code
activeProcessCount = 2;
pro1.Start();
pro2.Start();
}
答案 2 :(得分:1)
WaitForExit()是&#34;阻止&#34;你的界面从刷新,调用只是等待进程退出。作为替代方案,如果您需要在退出流程时执行此操作:
private void button1_Click(object sender, EventArgs e)
{
Process pro = new Process();
pro.StartInfo.FileName = "notepad";
pro.StartInfo.Arguments = "";
//if you need to do something when the process exits do this:
pro.EnableRaisingEvents = true;
pro.Exited += new EventHandler(pro_Exited);
pro.Start();
//pro.WaitForExit();
}
void pro_Exited(object sender, EventArgs e)
{
//do what you need here...
}
相反,您可以使用BackGroundWorker启动该过程。