2014-07-17 23 views
0

我的表單包含兩個控件:按鈕1和定時器如何計時器process.waiforexit()運行?

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; 
} 
+1

什麼使你相信計時器沒有運行?是否因爲文本框沒有更新?這並不意味着計時器沒有運行。 –

+0

刪除pro.WaitForExit(),它會繼續更新文本框 – terrybozzio

+0

@John Saunders,我試過不使用文本框,並替換像log.txt這樣的文本文件,每隔1秒我會將date_time寫入文件。但沒有看到結果。 –

回答

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(); 
} 
+0

在這種情況下包含1個進程。我可以使用你的代碼。但是如果解決方案包含多進程。 EX:process1,porcess2 我需要process1.WaitForExit()來運行process2 ... process3 .. –

+0

@NguyễnVănQuang我更新了我的答案。 –

+0

感謝您的answar。我在嘗試。我會再次告訴你 –

4

Process.WaitForExit

指示Process組件無限期等待關聯的過程退出。

你的計時器試圖調用timer1_Tick,但你的UI線程目前停留在等待的過程中退出,它不會。

你有兩個選擇,以解決此問題:

  1. 只需刪除調用WaitForExit如果你不真的需要等待
  2. 如果你確實需要時通知進程退出,設置Process.EnableRaisingEventstrue並註冊到Process.Exited事件
1

的WaitForExit()從清爽的「堵」的界面,通話只是等待那裏的進程退出。作爲選擇,如果你需要的時候爲退出的過程中這樣做是爲了做一些事情:

 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的過程。

相關問題